From b93cfb907facb14a890cf73988a652907d91bd38 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Mon, 22 Jan 2024 19:36:30 +0100 Subject: [PATCH 01/41] chore: extend chiado config from gnosis config (#6329) --- .../config/src/chainConfig/networks/chiado.ts | 19 ++++++------------- .../config/src/chainConfig/networks/gnosis.ts | 8 +++++--- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/packages/config/src/chainConfig/networks/chiado.ts b/packages/config/src/chainConfig/networks/chiado.ts index 284071f25bf8..0b7af5eaefec 100644 --- a/packages/config/src/chainConfig/networks/chiado.ts +++ b/packages/config/src/chainConfig/networks/chiado.ts @@ -1,32 +1,23 @@ /* eslint-disable @typescript-eslint/naming-convention */ import {fromHexString as b} from "@chainsafe/ssz"; -import {PresetName} from "@lodestar/params"; import {ChainConfig} from "../types.js"; -import {chainConfig as mainnet} from "../presets/mainnet.js"; +import {gnosisChainConfig as gnosis} from "./gnosis.js"; export const chiadoChainConfig: ChainConfig = { - ...mainnet, + ...gnosis, // NOTE: Only add diff values - PRESET_BASE: PresetName.gnosis, CONFIG_NAME: "chiado", // Transition TERMINAL_TOTAL_DIFFICULTY: BigInt("231707791542740786049188744689299064356246512"), - TERMINAL_BLOCK_HASH: b("0x0000000000000000000000000000000000000000000000000000000000000000"), - TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: Infinity, - SECONDS_PER_SLOT: 5, - SECONDS_PER_ETH1_BLOCK: 6, - ETH1_FOLLOW_DISTANCE: 1024, - CHURN_LIMIT_QUOTIENT: 4096, - - // Ethereum Goerli testnet + // Deposit contract DEPOSIT_CHAIN_ID: 10200, DEPOSIT_NETWORK_ID: 10200, DEPOSIT_CONTRACT_ADDRESS: b("0xb97036A26259B7147018913bD58a774cf91acf25"), - // Dec 8, 2021, 13:00 UTC + // 10 October 2022 10:00:00 GMT+0000 MIN_GENESIS_TIME: 1665396000, MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 6000, GENESIS_FORK_VERSION: b("0x0000006f"), @@ -41,4 +32,6 @@ export const chiadoChainConfig: ChainConfig = { // Capella CAPELLA_FORK_VERSION: b("0x0300006f"), CAPELLA_FORK_EPOCH: 244224, // Wed May 24 2023 13:12:00 GMT+0000 + // Deneb + DENEB_FORK_VERSION: b("0x0400006f"), }; diff --git a/packages/config/src/chainConfig/networks/gnosis.ts b/packages/config/src/chainConfig/networks/gnosis.ts index c952352f8438..22c038ba747a 100644 --- a/packages/config/src/chainConfig/networks/gnosis.ts +++ b/packages/config/src/chainConfig/networks/gnosis.ts @@ -13,15 +13,14 @@ export const gnosisChainConfig: ChainConfig = { // Transition TERMINAL_TOTAL_DIFFICULTY: BigInt("8626000000000000000000058750000000000000000000"), - TERMINAL_BLOCK_HASH: b("0x0000000000000000000000000000000000000000000000000000000000000000"), - TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: Infinity, + // Time parameters SECONDS_PER_SLOT: 5, SECONDS_PER_ETH1_BLOCK: 6, ETH1_FOLLOW_DISTANCE: 1024, CHURN_LIMIT_QUOTIENT: 4096, - // Ethereum Goerli testnet + // Deposit contract DEPOSIT_CHAIN_ID: 100, DEPOSIT_NETWORK_ID: 100, DEPOSIT_CONTRACT_ADDRESS: b("0x0b98057ea310f4d31f2a452b414647007d1645d9"), @@ -41,4 +40,7 @@ export const gnosisChainConfig: ChainConfig = { // Capella CAPELLA_FORK_VERSION: b("0x03000064"), CAPELLA_FORK_EPOCH: 648704, // 2023-08-01T11:34:20.000Z + // Deneb + DENEB_FORK_VERSION: b("0x04000064"), + DENEB_FORK_EPOCH: Infinity, }; From 4e49dbca4c6b2f8b2138a66bbb1e8c23a925bf8c Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Mon, 22 Jan 2024 19:41:58 +0100 Subject: [PATCH 02/41] fix: improve handling of non-integer builder boost factor values (#6332) --- .../validator-management/vc-configuration.md | 2 +- packages/cli/src/cmds/validator/handler.ts | 16 +++++++++++++--- packages/cli/src/cmds/validator/options.ts | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/pages/validator-management/vc-configuration.md b/docs/pages/validator-management/vc-configuration.md index cf8f3acae060..a1077997cd77 100644 --- a/docs/pages/validator-management/vc-configuration.md +++ b/docs/pages/validator-management/vc-configuration.md @@ -103,7 +103,7 @@ With Lodestar's `--builder.selection` validator options, you can select: #### Calculating builder boost factor with examples -To calculate the builder boost factor setting, you need to know what percentage you will accept a builder block for against a local execution block using the following formula: `100*100/(100+percentage)`. +To calculate the builder boost factor setting, you need to know what percentage you will accept a builder block for against a local execution block using the following formula: `100*100/(100+percentage)`. The value passed to `--builder.boostFactor` must be a valid number without decimals. Example 1: I will only accept a builder block with 25% more value than the local execution block. ``` diff --git a/packages/cli/src/cmds/validator/handler.ts b/packages/cli/src/cmds/validator/handler.ts index 5eca9bc741d9..91789c99ee3b 100644 --- a/packages/cli/src/cmds/validator/handler.ts +++ b/packages/cli/src/cmds/validator/handler.ts @@ -227,7 +227,7 @@ function getProposerConfigFromArgs( selection: parseBuilderSelection( args["builder.selection"] ?? (args["builder"] ? defaultOptions.builderAliasSelection : undefined) ), - boostFactor: args["builder.boostFactor"] !== undefined ? BigInt(args["builder.boostFactor"]) : undefined, + boostFactor: parseBuilderBoostFactor(args["builder.boostFactor"]), }, }; @@ -266,7 +266,7 @@ function parseBuilderSelection(builderSelection?: string): routes.validator.Buil case "executiononly": break; default: - throw Error("Invalid input for builder selection, check help."); + throw new YargsError("Invalid input for builder selection, check help"); } } return builderSelection as routes.validator.BuilderSelection; @@ -280,9 +280,19 @@ function parseBroadcastValidation(broadcastValidation?: string): routes.beacon.B case "consensus_and_equivocation": break; default: - throw Error("Invalid input for broadcastValidation, check help"); + throw new YargsError("Invalid input for broadcastValidation, check help"); } } return broadcastValidation as routes.beacon.BroadcastValidation; } + +function parseBuilderBoostFactor(boostFactor?: string): bigint | undefined { + if (boostFactor === undefined) return; + + if (!/^\d+$/.test(boostFactor)) { + throw new YargsError("Invalid input for builder boost factor, must be a valid number without decimals"); + } + + return BigInt(boostFactor); +} diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index cddb34981ce1..ecc8ad32ca87 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -45,7 +45,7 @@ export type IValidatorCliArgs = AccountValidatorArgs & builder?: boolean; "builder.selection"?: string; - "builder.boostFactor"?: bigint; + "builder.boostFactor"?: string; useProduceBlockV3?: boolean; broadcastValidation?: string; From 1f38b1b96cb2aa6e942aae506d818f054bb8480f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 13:44:16 -0500 Subject: [PATCH 03/41] chore(deps): bump vite from 5.0.6 to 5.0.12 (#6331) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.6 to 5.0.12. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v5.0.12/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.0.12/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c39d68175f13..27754c484466 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13510,9 +13510,9 @@ vite-plugin-top-level-await@^1.4.1: uuid "^9.0.1" vite@^5.0.0: - version "5.0.6" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.0.6.tgz#f9e13503a4c5ccd67312c67803dec921f3bdea7c" - integrity sha512-MD3joyAEBtV7QZPl2JVVUai6zHms3YOmLR+BpMzLlX2Yzjfcc4gTgNi09d/Rua3F4EtC8zdwPU8eQYyib4vVMQ== + version "5.0.12" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.0.12.tgz#8a2ffd4da36c132aec4adafe05d7adde38333c47" + integrity sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w== dependencies: esbuild "^0.19.3" postcss "^8.4.32" From 9b44056293e6e896a9ee8c297a9c3c97a1c5d88f Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Tue, 23 Jan 2024 08:25:12 +0100 Subject: [PATCH 04/41] feat: update configs to be able to support Deneb on all networks (#6328) * Move `MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS` from constants to config * Align structure / comments with consensus spec * Add references to preset / config files * Rename directory and files that contain config values * Add comment to networking params --- .../src/chain/archiver/archiveBlocks.ts | 4 ++-- packages/beacon-node/src/chain/blocks/types.ts | 4 ++-- .../reqresp/beaconBlocksMaybeBlobsByRange.ts | 4 ++-- .../network/gossip/scoringParameters.test.ts | 2 +- packages/cli/src/networks/dev.ts | 2 +- packages/config/package.json | 4 ++-- .../{presets => configs}/mainnet.ts | 18 +++++++++++++++++- .../{presets => configs}/minimal.ts | 15 +++++++++++++++ packages/config/src/chainConfig/default.ts | 4 ++-- .../config/src/chainConfig/networks/chiado.ts | 3 +++ .../src/chainConfig/networks/ephemery.ts | 2 +- .../config/src/chainConfig/networks/gnosis.ts | 5 ++++- .../config/src/chainConfig/networks/goerli.ts | 5 ++++- .../config/src/chainConfig/networks/holesky.ts | 2 +- .../config/src/chainConfig/networks/mainnet.ts | 2 +- .../config/src/chainConfig/networks/ropsten.ts | 2 +- .../config/src/chainConfig/networks/sepolia.ts | 4 ++-- packages/config/src/chainConfig/types.ts | 10 ++++++++-- packages/config/src/configs.ts | 4 ++++ packages/config/src/presets.ts | 4 ---- packages/params/src/index.ts | 1 - packages/params/src/presets/gnosis.ts | 3 +++ packages/params/src/presets/mainnet.ts | 4 +++- packages/params/src/presets/minimal.ts | 10 +++------- packages/validator/src/util/params.ts | 5 ++++- 25 files changed, 86 insertions(+), 37 deletions(-) rename packages/config/src/chainConfig/{presets => configs}/mainnet.ts (86%) rename packages/config/src/chainConfig/{presets => configs}/minimal.ts (88%) create mode 100644 packages/config/src/configs.ts delete mode 100644 packages/config/src/presets.ts diff --git a/packages/beacon-node/src/chain/archiver/archiveBlocks.ts b/packages/beacon-node/src/chain/archiver/archiveBlocks.ts index c88aa6cbf5ed..27934a6bae1f 100644 --- a/packages/beacon-node/src/chain/archiver/archiveBlocks.ts +++ b/packages/beacon-node/src/chain/archiver/archiveBlocks.ts @@ -2,7 +2,7 @@ import {fromHexString} from "@chainsafe/ssz"; import {Epoch, Slot, RootHex} from "@lodestar/types"; import {IForkChoice} from "@lodestar/fork-choice"; import {Logger, toHex} from "@lodestar/utils"; -import {ForkSeq, SLOTS_PER_EPOCH, MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS} from "@lodestar/params"; +import {ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params"; import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition"; import {KeyValue} from "@lodestar/db"; import {ChainForkConfig} from "@lodestar/config"; @@ -83,7 +83,7 @@ export async function archiveBlocks( // Delete expired blobs // Keep only `[max(GENESIS_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS), current_epoch]` if (finalizedPostDeneb) { - const blobSidecarsMinEpoch = currentEpoch - MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS; + const blobSidecarsMinEpoch = currentEpoch - config.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS; if (blobSidecarsMinEpoch >= config.DENEB_FORK_EPOCH) { const slotsToDelete = await db.blobSidecarsArchive.keys({lt: computeStartSlotAtEpoch(blobSidecarsMinEpoch)}); if (slotsToDelete.length > 0) { diff --git a/packages/beacon-node/src/chain/blocks/types.ts b/packages/beacon-node/src/chain/blocks/types.ts index aff5a64c9929..2fd16fa64705 100644 --- a/packages/beacon-node/src/chain/blocks/types.ts +++ b/packages/beacon-node/src/chain/blocks/types.ts @@ -1,7 +1,7 @@ import {CachedBeaconStateAllForks, computeEpochAtSlot, DataAvailableStatus} from "@lodestar/state-transition"; import {MaybeValidExecutionStatus} from "@lodestar/fork-choice"; import {allForks, deneb, Slot} from "@lodestar/types"; -import {ForkSeq, MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS} from "@lodestar/params"; +import {ForkSeq} from "@lodestar/params"; import {ChainForkConfig} from "@lodestar/config"; export enum BlockInputType { @@ -36,7 +36,7 @@ export function blockRequiresBlobs(config: ChainForkConfig, blockSlot: Slot, clo return ( config.getForkSeq(blockSlot) >= ForkSeq.deneb && // Only request blobs if they are recent enough - computeEpochAtSlot(blockSlot) >= computeEpochAtSlot(clockSlot) - MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS + computeEpochAtSlot(blockSlot) >= computeEpochAtSlot(clockSlot) - config.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS ); } diff --git a/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRange.ts b/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRange.ts index 41d3e901c41d..e57c3e5b7c8e 100644 --- a/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRange.ts +++ b/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRange.ts @@ -1,6 +1,6 @@ import {ChainForkConfig} from "@lodestar/config"; import {deneb, Epoch, phase0, allForks, Slot} from "@lodestar/types"; -import {ForkSeq, MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS} from "@lodestar/params"; +import {ForkSeq} from "@lodestar/params"; import {computeEpochAtSlot} from "@lodestar/state-transition"; import {BlockInput, BlockSource, getBlockInput} from "../../chain/blocks/types.js"; @@ -37,7 +37,7 @@ export async function beaconBlocksMaybeBlobsByRange( } // Only request blobs if they are recent enough - else if (computeEpochAtSlot(startSlot) >= currentEpoch - MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS) { + else 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), 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 6805f00ced1b..7ef09af2cd89 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 @@ -2,7 +2,7 @@ import {describe, it, expect} from "vitest"; import {TopicScoreParams} from "@chainsafe/libp2p-gossipsub/score"; import {ATTESTATION_SUBNET_COUNT, ForkName, SLOTS_PER_EPOCH} from "@lodestar/params"; import {createBeaconConfig} from "@lodestar/config"; -import {mainnetChainConfig} from "@lodestar/config/presets"; +import {mainnetChainConfig} from "@lodestar/config/configs"; import {computeGossipPeerScoreParams, gossipScoreThresholds} from "../../../../src/network/gossip/scoringParameters.js"; import {stringifyGossipTopic} from "../../../../src/network/gossip/topic.js"; import {GossipType} from "../../../../src/network/index.js"; diff --git a/packages/cli/src/networks/dev.ts b/packages/cli/src/networks/dev.ts index 77d55bc6a32d..ff8afc127dcc 100644 --- a/packages/cli/src/networks/dev.ts +++ b/packages/cli/src/networks/dev.ts @@ -1,5 +1,5 @@ import {gnosisChainConfig} from "@lodestar/config/networks"; -import {minimalChainConfig, mainnetChainConfig} from "@lodestar/config/presets"; +import {minimalChainConfig, mainnetChainConfig} from "@lodestar/config/configs"; import {ACTIVE_PRESET, PresetName} from "@lodestar/params"; let chainConfig; diff --git a/packages/config/package.json b/packages/config/package.json index c52a070b69fd..3b0a649e78c5 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -19,8 +19,8 @@ "./networks": { "import": "./lib/networks.js" }, - "./presets": { - "import": "./lib/presets.js" + "./configs": { + "import": "./lib/configs.js" } }, "typesVersions": { diff --git a/packages/config/src/chainConfig/presets/mainnet.ts b/packages/config/src/chainConfig/configs/mainnet.ts similarity index 86% rename from packages/config/src/chainConfig/presets/mainnet.ts rename to packages/config/src/chainConfig/configs/mainnet.ts index 2c02643a032c..f9c17ce1cb8e 100644 --- a/packages/config/src/chainConfig/presets/mainnet.ts +++ b/packages/config/src/chainConfig/configs/mainnet.ts @@ -3,7 +3,11 @@ import {fromHexString as b} from "@chainsafe/ssz"; import {PresetName} from "@lodestar/params"; import {ChainConfig} from "../types.js"; +// Mainnet config +// https://github.com/ethereum/consensus-specs/blob/dev/configs/mainnet.yaml + export const chainConfig: ChainConfig = { + // Extends the mainnet preset PRESET_BASE: PresetName.mainnet, CONFIG_NAME: "mainnet", @@ -41,7 +45,7 @@ export const chainConfig: ChainConfig = { CAPELLA_FORK_VERSION: b("0x03000000"), CAPELLA_FORK_EPOCH: 194048, // April 12 (epoch: 194048 slot: 6209536 UTC: 4/12/2023, 10:27:35 PM) - // DENEB + // Deneb DENEB_FORK_VERSION: b("0x04000000"), DENEB_FORK_EPOCH: Infinity, @@ -68,9 +72,14 @@ export const chainConfig: ChainConfig = { EJECTION_BALANCE: 16000000000, // 2**2 (= 4) MIN_PER_EPOCH_CHURN_LIMIT: 4, + // 2**3 (= 8) MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 8, // 2**16 (= 65,536) CHURN_LIMIT_QUOTIENT: 65536, + + // Fork choice + // --------------------------------------------------------------- + // 40% PROPOSER_SCORE_BOOST: 40, // Deposit contract @@ -79,4 +88,11 @@ export const chainConfig: ChainConfig = { DEPOSIT_CHAIN_ID: 1, DEPOSIT_NETWORK_ID: 1, DEPOSIT_CONTRACT_ADDRESS: b("0x00000000219ab540356cBB839Cbe05303d7705Fa"), + + // Networking + // --------------------------------------------------------------- + + // Deneb + // `2**12` (= 4096 epochs, ~18 days) + MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096, }; diff --git a/packages/config/src/chainConfig/presets/minimal.ts b/packages/config/src/chainConfig/configs/minimal.ts similarity index 88% rename from packages/config/src/chainConfig/presets/minimal.ts rename to packages/config/src/chainConfig/configs/minimal.ts index d790032bcee1..6c0a13d8abb2 100644 --- a/packages/config/src/chainConfig/presets/minimal.ts +++ b/packages/config/src/chainConfig/configs/minimal.ts @@ -3,6 +3,9 @@ import {fromHexString as b} from "@chainsafe/ssz"; import {PresetName} from "@lodestar/params"; import {ChainConfig} from "../types.js"; +// Minimal config +// https://github.com/ethereum/consensus-specs/blob/dev/configs/minimal.yaml + export const chainConfig: ChainConfig = { // Extends the minimal preset PRESET_BASE: PresetName.minimal, @@ -66,9 +69,14 @@ export const chainConfig: ChainConfig = { EJECTION_BALANCE: 16000000000, // 2**2 (= 4) MIN_PER_EPOCH_CHURN_LIMIT: 2, + // [customized] MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 4, // [customized] scale queue churn at much lower validator counts for testing CHURN_LIMIT_QUOTIENT: 32, + + // Fork choice + // --------------------------------------------------------------- + // 40% PROPOSER_SCORE_BOOST: 40, // Deposit contract @@ -78,4 +86,11 @@ export const chainConfig: ChainConfig = { DEPOSIT_NETWORK_ID: 5, // Configured on a per testnet basis DEPOSIT_CONTRACT_ADDRESS: b("0x1234567890123456789012345678901234567890"), + + // Networking + // --------------------------------------------------------------- + + // Deneb + // `2**12` (= 4096 epochs, ~18 days) + MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 4096, }; diff --git a/packages/config/src/chainConfig/default.ts b/packages/config/src/chainConfig/default.ts index 368f2afd067d..d778c9b82447 100644 --- a/packages/config/src/chainConfig/default.ts +++ b/packages/config/src/chainConfig/default.ts @@ -1,7 +1,7 @@ import {ACTIVE_PRESET, PresetName} from "@lodestar/params"; import {ChainConfig} from "./types.js"; -import {chainConfig as mainnet} from "./presets/mainnet.js"; -import {chainConfig as minimal} from "./presets/minimal.js"; +import {chainConfig as mainnet} from "./configs/mainnet.js"; +import {chainConfig as minimal} from "./configs/minimal.js"; let defaultChainConfig: ChainConfig; diff --git a/packages/config/src/chainConfig/networks/chiado.ts b/packages/config/src/chainConfig/networks/chiado.ts index 0b7af5eaefec..01739cf1d4eb 100644 --- a/packages/config/src/chainConfig/networks/chiado.ts +++ b/packages/config/src/chainConfig/networks/chiado.ts @@ -3,6 +3,9 @@ import {fromHexString as b} from "@chainsafe/ssz"; import {ChainConfig} from "../types.js"; import {gnosisChainConfig as gnosis} from "./gnosis.js"; +// Chiado beacon chain config: +// https://github.com/gnosischain/configs/blob/main/chiado/config.yaml + export const chiadoChainConfig: ChainConfig = { ...gnosis, diff --git a/packages/config/src/chainConfig/networks/ephemery.ts b/packages/config/src/chainConfig/networks/ephemery.ts index 5557767550bb..29e3f7b92d01 100644 --- a/packages/config/src/chainConfig/networks/ephemery.ts +++ b/packages/config/src/chainConfig/networks/ephemery.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import {fromHexString as b} from "@chainsafe/ssz"; import {ChainConfig} from "../types.js"; -import {chainConfig as mainnet} from "../presets/mainnet.js"; +import {chainConfig as mainnet} from "../configs/mainnet.js"; // Ephemery dynamic beacon chain config: // https://github.com/ephemery-testnet/ephemery-genesis/blob/master/cl-config.yaml diff --git a/packages/config/src/chainConfig/networks/gnosis.ts b/packages/config/src/chainConfig/networks/gnosis.ts index 22c038ba747a..6f3ccfed39e6 100644 --- a/packages/config/src/chainConfig/networks/gnosis.ts +++ b/packages/config/src/chainConfig/networks/gnosis.ts @@ -2,7 +2,10 @@ import {fromHexString as b} from "@chainsafe/ssz"; import {PresetName} from "@lodestar/params"; import {ChainConfig} from "../types.js"; -import {chainConfig as mainnet} from "../presets/mainnet.js"; +import {chainConfig as mainnet} from "../configs/mainnet.js"; + +// Gnosis beacon chain config: +// https://github.com/gnosischain/configs/blob/main/mainnet/config.yaml export const gnosisChainConfig: ChainConfig = { ...mainnet, diff --git a/packages/config/src/chainConfig/networks/goerli.ts b/packages/config/src/chainConfig/networks/goerli.ts index f1fc0ab2418c..b90f79f4e272 100644 --- a/packages/config/src/chainConfig/networks/goerli.ts +++ b/packages/config/src/chainConfig/networks/goerli.ts @@ -1,7 +1,10 @@ /* eslint-disable @typescript-eslint/naming-convention */ import {fromHexString as b} from "@chainsafe/ssz"; import {ChainConfig} from "../types.js"; -import {chainConfig as mainnet} from "../presets/mainnet.js"; +import {chainConfig as mainnet} from "../configs/mainnet.js"; + +// Goerli beacon chain config: +// https://github.com/eth-clients/goerli/blob/main/prater/config.yaml export const goerliChainConfig: ChainConfig = { ...mainnet, diff --git a/packages/config/src/chainConfig/networks/holesky.ts b/packages/config/src/chainConfig/networks/holesky.ts index e255369ccbaa..3115caf1ab76 100644 --- a/packages/config/src/chainConfig/networks/holesky.ts +++ b/packages/config/src/chainConfig/networks/holesky.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import {fromHexString as b} from "@chainsafe/ssz"; import {ChainConfig} from "../types.js"; -import {chainConfig as mainnet} from "../presets/mainnet.js"; +import {chainConfig as mainnet} from "../configs/mainnet.js"; // Holesky beacon chain config: // https://github.com/eth-clients/holesky/blob/main/custom_config_data/config.yaml diff --git a/packages/config/src/chainConfig/networks/mainnet.ts b/packages/config/src/chainConfig/networks/mainnet.ts index 1ae9858523e2..24584ad8442b 100644 --- a/packages/config/src/chainConfig/networks/mainnet.ts +++ b/packages/config/src/chainConfig/networks/mainnet.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import {fromHexString as b} from "@chainsafe/ssz"; import {ChainConfig} from "../types.js"; -import {chainConfig as mainnet} from "../presets/mainnet.js"; +import {chainConfig as mainnet} from "../configs/mainnet.js"; export const mainnetChainConfig: ChainConfig = { ...mainnet, diff --git a/packages/config/src/chainConfig/networks/ropsten.ts b/packages/config/src/chainConfig/networks/ropsten.ts index a94419c9140b..6bb7811ccba3 100644 --- a/packages/config/src/chainConfig/networks/ropsten.ts +++ b/packages/config/src/chainConfig/networks/ropsten.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import {fromHexString as b} from "@chainsafe/ssz"; import {ChainConfig} from "../types.js"; -import {chainConfig as mainnet} from "../presets/mainnet.js"; +import {chainConfig as mainnet} from "../configs/mainnet.js"; // Ropsten beacon chain config: // https://github.com/eth-clients/merge-testnets/blob/main/ropsten-beacon-chain/config.yaml diff --git a/packages/config/src/chainConfig/networks/sepolia.ts b/packages/config/src/chainConfig/networks/sepolia.ts index c81fda37b4c6..a3598299e294 100644 --- a/packages/config/src/chainConfig/networks/sepolia.ts +++ b/packages/config/src/chainConfig/networks/sepolia.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/naming-convention */ import {fromHexString as b} from "@chainsafe/ssz"; import {ChainConfig} from "../types.js"; -import {chainConfig as mainnet} from "../presets/mainnet.js"; +import {chainConfig as mainnet} from "../configs/mainnet.js"; // Sepolia beacon chain config: -// https://github.com/eth-clients/merge-testnets/blob/main/sepolia-beacon-chain/config.yaml +// https://github.com/eth-clients/sepolia/blob/main/bepolia/config.yaml export const sepoliaChainConfig: ChainConfig = { ...mainnet, diff --git a/packages/config/src/chainConfig/types.ts b/packages/config/src/chainConfig/types.ts index 4818ef9ee0aa..20e8119332f3 100644 --- a/packages/config/src/chainConfig/types.ts +++ b/packages/config/src/chainConfig/types.ts @@ -56,13 +56,16 @@ export type ChainConfig = { MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: number; CHURN_LIMIT_QUOTIENT: number; - // Proposer boost + // Fork choice PROPOSER_SCORE_BOOST: number; // Deposit contract DEPOSIT_CHAIN_ID: number; DEPOSIT_NETWORK_ID: number; DEPOSIT_CONTRACT_ADDRESS: Uint8Array; + + // Networking + MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: number; }; export const chainConfigTypes: SpecTypes = { @@ -109,13 +112,16 @@ export const chainConfigTypes: SpecTypes = { MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: "number", CHURN_LIMIT_QUOTIENT: "number", - // Proposer boost + // Fork choice PROPOSER_SCORE_BOOST: "number", // Deposit contract DEPOSIT_CHAIN_ID: "number", DEPOSIT_NETWORK_ID: "number", DEPOSIT_CONTRACT_ADDRESS: "bytes", + + // Networking + MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: "number", }; /** Allows values in a Spec file */ diff --git a/packages/config/src/configs.ts b/packages/config/src/configs.ts new file mode 100644 index 000000000000..9aded2b5190b --- /dev/null +++ b/packages/config/src/configs.ts @@ -0,0 +1,4 @@ +import {chainConfig as mainnetChainConfig} from "./chainConfig/configs/mainnet.js"; +import {chainConfig as minimalChainConfig} from "./chainConfig/configs/minimal.js"; + +export {mainnetChainConfig, minimalChainConfig}; diff --git a/packages/config/src/presets.ts b/packages/config/src/presets.ts deleted file mode 100644 index 542c01ece33d..000000000000 --- a/packages/config/src/presets.ts +++ /dev/null @@ -1,4 +0,0 @@ -import {chainConfig as mainnetChainConfig} from "./chainConfig/presets/mainnet.js"; -import {chainConfig as minimalChainConfig} from "./chainConfig/presets/minimal.js"; - -export {mainnetChainConfig, minimalChainConfig}; diff --git a/packages/params/src/index.ts b/packages/params/src/index.ts index e0623537d7f0..d111d090b8c3 100644 --- a/packages/params/src/index.ts +++ b/packages/params/src/index.ts @@ -179,7 +179,6 @@ export const SYNC_COMMITTEE_SUBNET_SIZE = Math.floor(SYNC_COMMITTEE_SIZE / SYNC_ export const MAX_REQUEST_BLOCKS = 2 ** 10; // 1024 export const MAX_REQUEST_BLOCKS_DENEB = 2 ** 7; // 128 export const MAX_REQUEST_BLOB_SIDECARS = MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK; -export const MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS = 2 ** 12; // 4096 epochs, ~18 days // Lightclient pre-computed /** diff --git a/packages/params/src/presets/gnosis.ts b/packages/params/src/presets/gnosis.ts index 2356e7d3d69e..412c38a6eb82 100644 --- a/packages/params/src/presets/gnosis.ts +++ b/packages/params/src/presets/gnosis.ts @@ -1,6 +1,9 @@ import {BeaconPreset} from "../types.js"; 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 9b591103edf5..42a705a07f03 100644 --- a/packages/params/src/presets/mainnet.ts +++ b/packages/params/src/presets/mainnet.ts @@ -1,5 +1,8 @@ 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 @@ -111,7 +114,6 @@ export const mainnetPreset: BeaconPreset = { // DENEB /////////// - // https://github.com/ethereum/consensus-specs/blob/dev/presets/mainnet/eip4844.yaml FIELD_ELEMENTS_PER_BLOB: 4096, MAX_BLOB_COMMITMENTS_PER_BLOCK: 4096, MAX_BLOBS_PER_BLOCK: 6, diff --git a/packages/params/src/presets/minimal.ts b/packages/params/src/presets/minimal.ts index ad86cbf89e61..b940841a0429 100644 --- a/packages/params/src/presets/minimal.ts +++ b/packages/params/src/presets/minimal.ts @@ -1,5 +1,8 @@ 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 @@ -42,12 +45,6 @@ export const minimalPreset: BeaconPreset = { EPOCHS_PER_ETH1_VOTING_PERIOD: 4, // [customized] smaller state SLOTS_PER_HISTORICAL_ROOT: 64, - /* - // 2**8 (= 256) epochs - MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256, - // [customized] higher frequency of committee turnover and faster time to acceptable voluntary exit - SHARD_COMMITTEE_PERIOD: 64, - */ // 2**2 (= 4) epochs MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4, @@ -118,7 +115,6 @@ export const minimalPreset: BeaconPreset = { // DENEB /////////// - // https://github.com/ethereum/consensus-specs/blob/dev/presets/minimal/eip4844.yaml FIELD_ELEMENTS_PER_BLOB: 4096, MAX_BLOB_COMMITMENTS_PER_BLOCK: 16, MAX_BLOBS_PER_BLOCK: 6, diff --git a/packages/validator/src/util/params.ts b/packages/validator/src/util/params.ts index 1431f4f3c56e..006ae3fadbbb 100644 --- a/packages/validator/src/util/params.ts +++ b/packages/validator/src/util/params.ts @@ -121,7 +121,7 @@ function getSpecCriticalParams(localConfig: ChainConfig): Record Date: Tue, 23 Jan 2024 15:04:35 +0100 Subject: [PATCH 05/41] feat: schedule deneb on chiado (#6342) --- packages/config/src/chainConfig/networks/chiado.ts | 1 + packages/config/src/chainConfig/networks/gnosis.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/packages/config/src/chainConfig/networks/chiado.ts b/packages/config/src/chainConfig/networks/chiado.ts index 01739cf1d4eb..43b13a210dac 100644 --- a/packages/config/src/chainConfig/networks/chiado.ts +++ b/packages/config/src/chainConfig/networks/chiado.ts @@ -37,4 +37,5 @@ export const chiadoChainConfig: ChainConfig = { CAPELLA_FORK_EPOCH: 244224, // Wed May 24 2023 13:12:00 GMT+0000 // Deneb DENEB_FORK_VERSION: b("0x0400006f"), + DENEB_FORK_EPOCH: 516608, // Wed Jan 31 2024 18:15:40 GMT+0000 }; diff --git a/packages/config/src/chainConfig/networks/gnosis.ts b/packages/config/src/chainConfig/networks/gnosis.ts index 6f3ccfed39e6..7bafaa0225b1 100644 --- a/packages/config/src/chainConfig/networks/gnosis.ts +++ b/packages/config/src/chainConfig/networks/gnosis.ts @@ -23,11 +23,17 @@ export const gnosisChainConfig: ChainConfig = { ETH1_FOLLOW_DISTANCE: 1024, CHURN_LIMIT_QUOTIENT: 4096, + // Validator cycle + MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT: 2, + // Deposit contract DEPOSIT_CHAIN_ID: 100, DEPOSIT_NETWORK_ID: 100, DEPOSIT_CONTRACT_ADDRESS: b("0x0b98057ea310f4d31f2a452b414647007d1645d9"), + // Networking + MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS: 16384, + // Dec 8, 2021, 13:00 UTC MIN_GENESIS_TIME: 1638968400, MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 4096, From 43994ba8ef665c98d7ec6dcbb5338ebf5906f249 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Tue, 23 Jan 2024 17:05:04 +0100 Subject: [PATCH 06/41] fix: update beacon max-old-space-size to 8192 (#6343) * feat: increase default memory limit to 8GB * Revise comments --- Dockerfile | 6 +++--- docker-compose.yml | 6 +++--- docs/pages/tools/flamegraphs.md | 2 +- lodestar | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5a9541e06f1a..a9e597c2fb9f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,9 +39,9 @@ FROM node:20-alpine WORKDIR /usr/app COPY --from=build_deps /usr/app . -# NodeJS applications have a default memory limit of 2.5GB. -# This limit is bit tight for a Prater node, it is recommended to raise the limit +# NodeJS applications have a default memory limit of 4GB on most machines. +# This limit is bit tight for a Mainnet node, it is recommended to raise the limit # since memory may spike during certain network conditions. -ENV NODE_OPTIONS=--max-old-space-size=4096 +ENV NODE_OPTIONS=--max-old-space-size=8192 ENTRYPOINT ["node", "./packages/cli/bin/lodestar"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index cab1245d351e..d8c6122e3537 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,11 +11,11 @@ services: - "9000:9000" # P2P port # - "9596:9596" # REST API port command: beacon --dataDir /data --rest --rest.address 0.0.0.0 --metrics --logFile /logs/beacon.log --logFileLevel debug --logFileDailyRotate 5 - # NodeJS applications have a default memory limit of 2.5GB. - # This limit is bit tight for a Prater node, it is recommended to raise the limit + # NodeJS applications have a default memory limit of 4GB on most machines. + # This limit is bit tight for a Mainnet node, it is recommended to raise the limit # since memory may spike during certain network conditions. environment: - NODE_OPTIONS: --max-old-space-size=4096 + NODE_OPTIONS: --max-old-space-size=8192 prometheus: build: docker/prometheus diff --git a/docs/pages/tools/flamegraphs.md b/docs/pages/tools/flamegraphs.md index d6f45303a9aa..119cc7dc10e5 100644 --- a/docs/pages/tools/flamegraphs.md +++ b/docs/pages/tools/flamegraphs.md @@ -18,7 +18,7 @@ Next we need to update the Lodestar service by modifying the start script. We ne ```sh node \ --perf-basic-prof \ - --max-old-space-size=4096 \ + --max-old-space-size=8192 \ /usr/src/lodestar/packages/cli/bin/lodestar \ beacon \ --rcConfig /home/devops/beacon/rcconfig.yml diff --git a/lodestar b/lodestar index 2101d94b77cb..0b20ba4c9bcd 100755 --- a/lodestar +++ b/lodestar @@ -2,6 +2,6 @@ # Convenience script to run the lodestar binary from built source # -# ./lodestar.sh beacon --network prater +# ./lodestar.sh beacon --network mainnet -node --trace-deprecation --max-old-space-size=4096 ./packages/cli/bin/lodestar.js "$@" \ No newline at end of file +node --trace-deprecation --max-old-space-size=8192 ./packages/cli/bin/lodestar.js "$@" \ No newline at end of file From 92ed3479a6ac59b75d100b9738ee437b2e80a748 Mon Sep 17 00:00:00 2001 From: Phil Ngo Date: Tue, 23 Jan 2024 11:06:39 -0500 Subject: [PATCH 07/41] v1.15.0 --- lerna.json | 2 +- packages/api/package.json | 10 +++++----- packages/beacon-node/package.json | 26 +++++++++++++------------- packages/cli/package.json | 26 +++++++++++++------------- packages/config/package.json | 6 +++--- packages/db/package.json | 8 ++++---- packages/flare/package.json | 14 +++++++------- packages/fork-choice/package.json | 12 ++++++------ packages/light-client/package.json | 14 +++++++------- packages/logger/package.json | 6 +++--- packages/params/package.json | 2 +- packages/prover/package.json | 18 +++++++++--------- packages/reqresp/package.json | 12 ++++++------ packages/spec-test-util/package.json | 8 ++++---- packages/state-transition/package.json | 10 +++++----- packages/test-utils/package.json | 6 +++--- packages/types/package.json | 4 ++-- packages/utils/package.json | 2 +- packages/validator/package.json | 18 +++++++++--------- 19 files changed, 102 insertions(+), 102 deletions(-) diff --git a/lerna.json b/lerna.json index 487caa95b0a2..2a9439d49715 100644 --- a/lerna.json +++ b/lerna.json @@ -4,7 +4,7 @@ ], "npmClient": "yarn", "useNx": true, - "version": "1.14.0", + "version": "1.15.0", "stream": true, "command": { "version": { diff --git a/packages/api/package.json b/packages/api/package.json index e1a52c47b489..533961953b9a 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": { ".": { @@ -71,10 +71,10 @@ "dependencies": { "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/ssz": "^0.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/config": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0", "eventsource": "^2.0.2", "qs": "^6.11.1" }, diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 3ddde8540670..8ce625fb0d54 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": { ".": { @@ -121,18 +121,18 @@ "@libp2p/peer-id-factory": "^4.0.3", "@libp2p/prometheus-metrics": "^3.0.10", "@libp2p/tcp": "9.0.10", - "@lodestar/api": "^1.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/db": "^1.14.0", - "@lodestar/fork-choice": "^1.14.0", - "@lodestar/light-client": "^1.14.0", - "@lodestar/logger": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/reqresp": "^1.14.0", - "@lodestar/state-transition": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0", - "@lodestar/validator": "^1.14.0", + "@lodestar/api": "^1.15.0", + "@lodestar/config": "^1.15.0", + "@lodestar/db": "^1.15.0", + "@lodestar/fork-choice": "^1.15.0", + "@lodestar/light-client": "^1.15.0", + "@lodestar/logger": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/reqresp": "^1.15.0", + "@lodestar/state-transition": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0", + "@lodestar/validator": "^1.15.0", "@multiformats/multiaddr": "^12.1.3", "@types/datastore-level": "^3.0.0", "buffer-xor": "^2.0.2", diff --git a/packages/cli/package.json b/packages/cli/package.json index 243dee688417..616dce9d4f68 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@chainsafe/lodestar", - "version": "1.14.0", + "version": "1.15.0", "description": "Command line interface for lodestar", "author": "ChainSafe Systems", "license": "LGPL-3.0", @@ -66,17 +66,17 @@ "@libp2p/crypto": "^3.0.4", "@libp2p/peer-id": "^4.0.4", "@libp2p/peer-id-factory": "^4.0.3", - "@lodestar/api": "^1.14.0", - "@lodestar/beacon-node": "^1.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/db": "^1.14.0", - "@lodestar/light-client": "^1.14.0", - "@lodestar/logger": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/state-transition": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0", - "@lodestar/validator": "^1.14.0", + "@lodestar/api": "^1.15.0", + "@lodestar/beacon-node": "^1.15.0", + "@lodestar/config": "^1.15.0", + "@lodestar/db": "^1.15.0", + "@lodestar/light-client": "^1.15.0", + "@lodestar/logger": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/state-transition": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0", + "@lodestar/validator": "^1.15.0", "@multiformats/multiaddr": "^12.1.3", "@types/lockfile": "^1.0.2", "bip39": "^3.1.0", @@ -97,7 +97,7 @@ "yargs": "^17.7.1" }, "devDependencies": { - "@lodestar/test-utils": "^1.14.0", + "@lodestar/test-utils": "^1.15.0", "@types/debug": "^4.1.7", "@types/expand-tilde": "^2.0.0", "@types/got": "^9.6.12", diff --git a/packages/config/package.json b/packages/config/package.json index 3b0a649e78c5..a36da8c6240a 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/config", - "version": "1.14.0", + "version": "1.15.0", "description": "Chain configuration required for lodestar", "author": "ChainSafe Systems", "license": "Apache-2.0", @@ -65,7 +65,7 @@ ], "dependencies": { "@chainsafe/ssz": "^0.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/types": "^1.14.0" + "@lodestar/params": "^1.15.0", + "@lodestar/types": "^1.15.0" } } diff --git a/packages/db/package.json b/packages/db/package.json index d99b21d80b9b..f11e5b48995c 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/db", - "version": "1.14.0", + "version": "1.15.0", "description": "DB modules of Lodestar", "author": "ChainSafe Systems", "homepage": "https://github.com/ChainSafe/lodestar#readme", @@ -38,13 +38,13 @@ }, "dependencies": { "@chainsafe/ssz": "^0.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/config": "^1.15.0", + "@lodestar/utils": "^1.15.0", "@types/levelup": "^4.3.3", "it-all": "^3.0.4", "level": "^8.0.0" }, "devDependencies": { - "@lodestar/logger": "^1.14.0" + "@lodestar/logger": "^1.15.0" } } diff --git a/packages/flare/package.json b/packages/flare/package.json index 7417cf93c63d..93973110ab8a 100644 --- a/packages/flare/package.json +++ b/packages/flare/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/flare", - "version": "1.14.0", + "version": "1.15.0", "description": "Beacon chain debugging tool", "author": "ChainSafe Systems", "license": "Apache-2.0", @@ -60,12 +60,12 @@ "dependencies": { "@chainsafe/bls": "7.1.1", "@chainsafe/bls-keygen": "^0.3.0", - "@lodestar/api": "^1.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/state-transition": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/api": "^1.15.0", + "@lodestar/config": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/state-transition": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0", "source-map-support": "^0.5.21", "yargs": "^17.7.1" }, diff --git a/packages/fork-choice/package.json b/packages/fork-choice/package.json index 495c67a8e80b..606dec811bbc 100644 --- a/packages/fork-choice/package.json +++ b/packages/fork-choice/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": "./lib/index.js", "types": "./lib/index.d.ts", @@ -39,11 +39,11 @@ }, "dependencies": { "@chainsafe/ssz": "^0.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/state-transition": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0" + "@lodestar/config": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/state-transition": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0" }, "keywords": [ "ethereum", diff --git a/packages/light-client/package.json b/packages/light-client/package.json index dee231409730..456600cbd0bc 100644 --- a/packages/light-client/package.json +++ b/packages/light-client/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": { ".": { @@ -70,12 +70,12 @@ "@chainsafe/bls": "7.1.1", "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/ssz": "^0.14.0", - "@lodestar/api": "^1.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/state-transition": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/api": "^1.15.0", + "@lodestar/config": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/state-transition": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0", "mitt": "^3.0.0", "strict-event-emitter-types": "^2.0.0" }, diff --git a/packages/logger/package.json b/packages/logger/package.json index 2f450ee5be12..f1a5ddad1a06 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": { ".": { @@ -66,14 +66,14 @@ }, "types": "lib/index.d.ts", "dependencies": { - "@lodestar/utils": "^1.14.0", + "@lodestar/utils": "^1.15.0", "winston": "^3.8.2", "winston-daily-rotate-file": "^4.7.1", "winston-transport": "^4.5.0" }, "devDependencies": { "@chainsafe/threads": "^1.11.1", - "@lodestar/test-utils": "^1.14.0", + "@lodestar/test-utils": "^1.15.0", "@types/triple-beam": "^1.3.2", "rimraf": "^4.4.1", "triple-beam": "^1.3.0" diff --git a/packages/params/package.json b/packages/params/package.json index 2586c73566aa..d41dae06816e 100644 --- a/packages/params/package.json +++ b/packages/params/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/params", - "version": "1.14.0", + "version": "1.15.0", "description": "Chain parameters required for lodestar", "author": "ChainSafe Systems", "license": "Apache-2.0", diff --git a/packages/prover/package.json b/packages/prover/package.json index 05f7c33579b4..600f4b4d4d75 100644 --- a/packages/prover/package.json +++ b/packages/prover/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": { ".": { @@ -72,13 +72,13 @@ "@ethereumjs/tx": "^4.1.2", "@ethereumjs/util": "^8.0.6", "@ethereumjs/vm": "^6.4.2", - "@lodestar/api": "^1.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/light-client": "^1.14.0", - "@lodestar/logger": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/api": "^1.15.0", + "@lodestar/config": "^1.15.0", + "@lodestar/light-client": "^1.15.0", + "@lodestar/logger": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0", "ethereum-cryptography": "^1.2.0", "find-up": "^6.3.0", "http-proxy": "^1.18.1", @@ -87,7 +87,7 @@ "yargs": "^17.7.1" }, "devDependencies": { - "@lodestar/test-utils": "^1.14.0", + "@lodestar/test-utils": "^1.15.0", "@types/http-proxy": "^1.17.10", "@types/yargs": "^17.0.24", "axios": "^1.3.4", diff --git a/packages/reqresp/package.json b/packages/reqresp/package.json index c19af565c397..3856177449d3 100644 --- a/packages/reqresp/package.json +++ b/packages/reqresp/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": { ".": { @@ -56,9 +56,9 @@ "dependencies": { "@chainsafe/fast-crc32c": "^4.1.1", "@libp2p/interface": "^1.1.1", - "@lodestar/config": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/config": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/utils": "^1.15.0", "it-all": "^3.0.4", "it-pipe": "^3.0.1", "snappy": "^7.2.2", @@ -67,8 +67,8 @@ "uint8arraylist": "^2.4.7" }, "devDependencies": { - "@lodestar/logger": "^1.14.0", - "@lodestar/types": "^1.14.0", + "@lodestar/logger": "^1.15.0", + "@lodestar/types": "^1.15.0", "libp2p": "1.1.1" }, "peerDependencies": { diff --git a/packages/spec-test-util/package.json b/packages/spec-test-util/package.json index 899d6438d939..f8d953e408fd 100644 --- a/packages/spec-test-util/package.json +++ b/packages/spec-test-util/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/spec-test-util", - "version": "1.14.0", + "version": "1.15.0", "description": "Spec test suite generator from yaml test files", "author": "ChainSafe Systems", "license": "Apache-2.0", @@ -62,13 +62,13 @@ "blockchain" ], "dependencies": { - "@lodestar/utils": "^1.14.0", + "@lodestar/utils": "^1.15.0", "async-retry": "^1.3.3", "axios": "^1.3.4", - "vitest": "^1.2.1", "rimraf": "^4.4.1", "snappyjs": "^0.7.0", - "tar": "^6.1.13" + "tar": "^6.1.13", + "vitest": "^1.2.1" }, "devDependencies": { "@types/async-retry": "1.4.3", diff --git a/packages/state-transition/package.json b/packages/state-transition/package.json index cbde9b062177..8a1aea19f140 100644 --- a/packages/state-transition/package.json +++ b/packages/state-transition/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": { ".": { @@ -63,10 +63,10 @@ "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/persistent-ts": "^0.19.1", "@chainsafe/ssz": "^0.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/config": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0", "bigint-buffer": "^1.1.5", "buffer-xor": "^2.0.2" }, diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index d4a1df589e8f..038cd743bdd7 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@lodestar/test-utils", "private": true, - "version": "1.14.0", + "version": "1.15.0", "description": "Test utilities reused across other packages", "author": "ChainSafe Systems", "license": "Apache-2.0", @@ -60,8 +60,8 @@ "dependencies": { "@chainsafe/bls": "7.1.1", "@chainsafe/bls-keystore": "^3.0.0", - "@lodestar/params": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/params": "^1.15.0", + "@lodestar/utils": "^1.15.0", "axios": "^1.3.4", "testcontainers": "^10.2.1", "tmp": "^0.2.1", diff --git a/packages/types/package.json b/packages/types/package.json index b51acbef6801..1e9b811becfa 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": { ".": { @@ -73,7 +73,7 @@ "types": "lib/index.d.ts", "dependencies": { "@chainsafe/ssz": "^0.14.0", - "@lodestar/params": "^1.14.0" + "@lodestar/params": "^1.15.0" }, "keywords": [ "ethereum", diff --git a/packages/utils/package.json b/packages/utils/package.json index fcc0f5ac36c1..fa1dd4fdd829 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.14.0", + "version": "1.15.0", "type": "module", "exports": "./lib/index.js", "files": [ diff --git a/packages/validator/package.json b/packages/validator/package.json index 92c3e92d04a1..020792107c3b 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/validator", - "version": "1.14.0", + "version": "1.15.0", "description": "A Typescript implementation of the validator client", "author": "ChainSafe Systems", "license": "LGPL-3.0", @@ -49,18 +49,18 @@ "dependencies": { "@chainsafe/bls": "7.1.1", "@chainsafe/ssz": "^0.14.0", - "@lodestar/api": "^1.14.0", - "@lodestar/config": "^1.14.0", - "@lodestar/db": "^1.14.0", - "@lodestar/params": "^1.14.0", - "@lodestar/state-transition": "^1.14.0", - "@lodestar/types": "^1.14.0", - "@lodestar/utils": "^1.14.0", + "@lodestar/api": "^1.15.0", + "@lodestar/config": "^1.15.0", + "@lodestar/db": "^1.15.0", + "@lodestar/params": "^1.15.0", + "@lodestar/state-transition": "^1.15.0", + "@lodestar/types": "^1.15.0", + "@lodestar/utils": "^1.15.0", "bigint-buffer": "^1.1.5", "strict-event-emitter-types": "^2.0.0" }, "devDependencies": { - "@lodestar/test-utils": "^1.14.0", + "@lodestar/test-utils": "^1.15.0", "bigint-buffer": "^1.1.5", "rimraf": "^4.4.1" } From 01d47b9a0901c9f03a01ef68c819f4e592cbfd8b Mon Sep 17 00:00:00 2001 From: Julien Date: Thu, 25 Jan 2024 02:00:48 -0800 Subject: [PATCH 08/41] chore: align test scripts (#6339) * chore: align yarn test scripts * fix: handle prover stratup failure * fix: lint * chore: improve test guide * chore: introduce top level download-spec-tests script * chore: remove pretest scripts --- CONTRIBUTING.md | 8 ++++++++ package.json | 1 + packages/api/package.json | 3 +-- packages/beacon-node/package.json | 1 - packages/cli/package.json | 1 - packages/config/package.json | 2 +- packages/db/package.json | 1 - packages/flare/package.json | 2 +- packages/fork-choice/package.json | 1 - packages/light-client/package.json | 3 +-- packages/logger/package.json | 2 +- packages/params/package.json | 2 +- packages/prover/package.json | 1 - packages/prover/test/e2e/cli/cmds/start.test.ts | 6 ++++-- packages/reqresp/package.json | 1 - packages/spec-test-util/package.json | 2 +- packages/state-transition/package.json | 1 + packages/test-utils/package.json | 1 - packages/types/package.json | 1 + packages/utils/package.json | 1 - packages/validator/package.json | 3 +-- 21 files changed, 23 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a4e67c4d226b..4074c47e88e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,6 +32,14 @@ To run tests: - :test_tube: Run `yarn check-types` to check TypeScript types. - :test_tube: Run `yarn lint` to run the linter (ESLint). +Note that to run `test:e2e`, first ensure that the environment is correctly setup by running the `run_e2e_env.sh` script. + +```sh +GETH_DOCKER_IMAGE=ethereum/client-go:v1.11.6 NETHERMIND_DOCKER_IMAGE=nethermind/nethermind:1.18.0 ./scripts/run_e2e_env.sh start +``` + +Similarly, run `yarn download-spec-tests` before running `yarn test:spec`. + Contributing to tests: - Test must not depend on external live resources, such that running tests for a commit must be deterministic: diff --git a/package.json b/package.json index 93b364359a38..5d7a90f27e6f 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "test:browsers": "lerna run test:browsers", "test:e2e": "lerna run test:e2e --concurrency 1", "test:e2e:sim": "lerna run test:e2e:sim", + "download-spec-tests": "lerna run download-spec-tests", "test:spec": "lerna run test:spec", "test-coverage:unit": "c8 --config .c8rc.json --report-dir coverage/unit/ --all npm run test:unit", "test-coverage:browsers": "c8 --config .c8rc.json --report-dir coverage/browsers/ --all npm run test:browsers", diff --git a/packages/api/package.json b/packages/api/package.json index e1a52c47b489..0aa48470296d 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -63,8 +63,7 @@ "coverage": "codecov -F lodestar-api", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", - "test": "yarn test:unit && yarn test:e2e", + "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" }, diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 3ddde8540670..7b1bf0206011 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -75,7 +75,6 @@ "coverage": "codecov -F lodestar", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "test": "yarn test:unit && yarn test:e2e", "test:unit:minimal": "vitest --run --segfaultRetry 3 --dir test/unit/", "test:unit:mainnet": "LODESTAR_PRESET=mainnet vitest --run --dir test/unit-mainnet", diff --git a/packages/cli/package.json b/packages/cli/package.json index 243dee688417..368637c8983a 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -30,7 +30,6 @@ "docs:build": "node --loader ts-node/esm ./docsgen/index.ts", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "test:unit": "vitest --run --dir test/unit/", "test:e2e": "vitest --run --config vitest.config.e2e.ts --dir test/e2e/", "test:sim:multifork": "LODESTAR_PRESET=minimal node --loader ts-node/esm test/sim/multi_fork.test.ts", diff --git a/packages/config/package.json b/packages/config/package.json index 3b0a649e78c5..12c16f383fa8 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -49,7 +49,7 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", + "test": "yarn test:unit", "test:unit": "yarn vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" }, diff --git a/packages/db/package.json b/packages/db/package.json index d99b21d80b9b..64d499bd7fc1 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -31,7 +31,6 @@ "coverage": "codecov -F lodestar-fork-choice", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" diff --git a/packages/flare/package.json b/packages/flare/package.json index 7417cf93c63d..8106e2b85c7f 100644 --- a/packages/flare/package.json +++ b/packages/flare/package.json @@ -43,7 +43,7 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", + "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" }, diff --git a/packages/fork-choice/package.json b/packages/fork-choice/package.json index 495c67a8e80b..6436a4299ff5 100644 --- a/packages/fork-choice/package.json +++ b/packages/fork-choice/package.json @@ -32,7 +32,6 @@ "coverage": "codecov -F lodestar-fork-choice", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" diff --git a/packages/light-client/package.json b/packages/light-client/package.json index dee231409730..f09f4fdaffb9 100644 --- a/packages/light-client/package.json +++ b/packages/light-client/package.json @@ -57,8 +57,7 @@ "coverage": "codecov -F lodestar-light-client", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", - "test": "yarn test:unit && yarn test:e2e", + "test": "yarn test:unit", "test:unit": "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/logger/package.json b/packages/logger/package.json index 2f450ee5be12..f5efd6587bb4 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -55,7 +55,7 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", + "test": "yarn test:unit && yarn test:e2e", "test: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/params/package.json b/packages/params/package.json index 2586c73566aa..ae2bb4d66cc2 100644 --- a/packages/params/package.json +++ b/packages/params/package.json @@ -52,7 +52,7 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "test": "yarn run check-types", + "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", "test:browsers:chrome": "vitest --run --browser chrome --config ./vitest.browser.config.ts --dir test/unit", diff --git a/packages/prover/package.json b/packages/prover/package.json index 05f7c33579b4..15066cfd81ce 100644 --- a/packages/prover/package.json +++ b/packages/prover/package.json @@ -51,7 +51,6 @@ "coverage": "codecov -F lodestar-api", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "test": "yarn test:unit && yarn test:e2e", "test: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/test/e2e/cli/cmds/start.test.ts b/packages/prover/test/e2e/cli/cmds/start.test.ts index da0c9dceb405..8888b3ce84d5 100644 --- a/packages/prover/test/e2e/cli/cmds/start.test.ts +++ b/packages/prover/test/e2e/cli/cmds/start.test.ts @@ -43,7 +43,7 @@ describe("prover/start", () => { }); describe("when started", () => { - let proc: childProcess.ChildProcess; + let proc: childProcess.ChildProcess | null = null; const paramsFilePath = path.join("/tmp", "e2e-test-env", "params.json"); const web3: Web3 = new Web3(proxyUrl); @@ -74,7 +74,9 @@ describe("prover/start", () => { }, 50000); afterAll(async () => { - await stopChildProcess(proc); + if (proc) { + await stopChildProcess(proc); + } }); it("should respond to verified calls", async () => { diff --git a/packages/reqresp/package.json b/packages/reqresp/package.json index c19af565c397..9ac7472cd6cf 100644 --- a/packages/reqresp/package.json +++ b/packages/reqresp/package.json @@ -48,7 +48,6 @@ "coverage": "codecov -F lodestar-api", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" diff --git a/packages/spec-test-util/package.json b/packages/spec-test-util/package.json index 899d6438d939..5e6461863947 100644 --- a/packages/spec-test-util/package.json +++ b/packages/spec-test-util/package.json @@ -46,7 +46,7 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", + "test": "yarn test:unit && yarn test:e2e", "test:unit": "vitest --run --passWithNoTests --dir test/unit/", "test:e2e": "vitest --run --config vitest.config.e2e.ts --dir test/e2e/", "check-readme": "typescript-docs-verifier" diff --git a/packages/state-transition/package.json b/packages/state-transition/package.json index cbde9b062177..acba374e6e64 100644 --- a/packages/state-transition/package.json +++ b/packages/state-transition/package.json @@ -52,6 +52,7 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", + "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" }, diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index d4a1df589e8f..b1aaf3b16a33 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -44,7 +44,6 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "check-readme": "typescript-docs-verifier" }, "repository": { diff --git a/packages/types/package.json b/packages/types/package.json index b51acbef6801..4497098c14f4 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -61,6 +61,7 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", + "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/", "test:unit": "wrapper() { yarn test:constants:minimal $@ && yarn test:constants:mainnet $@ && vitest --run --dir test/unit/ $@; }; wrapper", diff --git a/packages/utils/package.json b/packages/utils/package.json index fcc0f5ac36c1..db3ed9e06986 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -30,7 +30,6 @@ "check-types": "tsc && vitest --run --typecheck --dir test/types/", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "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/validator/package.json b/packages/validator/package.json index 92c3e92d04a1..9b8fc03c942d 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -27,9 +27,8 @@ "check-types": "tsc", "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", - "pretest": "yarn run check-types", "test:unit": "vitest --run --dir test/unit/", - "test": "yarn test:unit", + "test": "yarn test:unit && yarn test:e2e", "test:spec": "vitest --run --config vitest.config.spec.ts --dir test/spec/", "test:e2e": "LODESTAR_PRESET=mainnet vitest --run --config vitest.config.e2e.ts --dir test/e2e", "download-spec-tests": "node --loader=ts-node/esm test/spec/downloadTests.ts", From 347c95fb0da219b5a4d551b7ce014f2ceda7ae48 Mon Sep 17 00:00:00 2001 From: g11tech Date: Fri, 26 Jan 2024 22:28:28 +0530 Subject: [PATCH 09/41] feat: allow builder boost factor to be configured via proposer config file (#6357) * feat: allow builder boost factor to be configured via proposer config file * reuse parseBuilderBoostFactor fn * re-shuffle fns and add builder selection validation --- packages/cli/src/cmds/validator/handler.ts | 29 +------------- packages/cli/src/util/proposerConfig.ts | 38 ++++++++++++++++++- .../validator/parseProposerConfig.test.ts | 3 ++ .../validator/proposerConfigs/validData.yaml | 2 + 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/packages/cli/src/cmds/validator/handler.ts b/packages/cli/src/cmds/validator/handler.ts index 91789c99ee3b..a98eb0755ad0 100644 --- a/packages/cli/src/cmds/validator/handler.ts +++ b/packages/cli/src/cmds/validator/handler.ts @@ -22,6 +22,7 @@ import {GlobalArgs} from "../../options/index.js"; import {YargsError, cleanOldLogFiles, getDefaultGraffiti, mkdir, parseLoggerArgs} from "../../util/index.js"; import {onGracefulShutdown, parseFeeRecipient, parseProposerConfig} from "../../util/index.js"; import {getVersionData} from "../../util/version.js"; +import {parseBuilderSelection, parseBuilderBoostFactor} from "../../util/proposerConfig.js"; import {getAccountPaths, getValidatorPaths} from "./paths.js"; import {IValidatorCliArgs, validatorMetricsDefaultOptions, validatorMonitoringDefaultOptions} from "./options.js"; import {getSignersFromArgs} from "./signers/index.js"; @@ -254,24 +255,6 @@ function getProposerConfigFromArgs( return valProposerConfig; } -function parseBuilderSelection(builderSelection?: string): routes.validator.BuilderSelection | undefined { - if (builderSelection) { - switch (builderSelection) { - case "maxprofit": - break; - case "builderalways": - break; - case "builderonly": - break; - case "executiononly": - break; - default: - throw new YargsError("Invalid input for builder selection, check help"); - } - } - return builderSelection as routes.validator.BuilderSelection; -} - function parseBroadcastValidation(broadcastValidation?: string): routes.beacon.BroadcastValidation | undefined { if (broadcastValidation) { switch (broadcastValidation) { @@ -286,13 +269,3 @@ function parseBroadcastValidation(broadcastValidation?: string): routes.beacon.B return broadcastValidation as routes.beacon.BroadcastValidation; } - -function parseBuilderBoostFactor(boostFactor?: string): bigint | undefined { - if (boostFactor === undefined) return; - - if (!/^\d+$/.test(boostFactor)) { - throw new YargsError("Invalid input for builder boost factor, must be a valid number without decimals"); - } - - return BigInt(boostFactor); -} diff --git a/packages/cli/src/util/proposerConfig.ts b/packages/cli/src/util/proposerConfig.ts index 2f3c71236255..661c81ee63af 100644 --- a/packages/cli/src/util/proposerConfig.ts +++ b/packages/cli/src/util/proposerConfig.ts @@ -8,6 +8,7 @@ import {routes} from "@lodestar/api"; import {parseFeeRecipient} from "./feeRecipient.js"; import {readFile} from "./file.js"; +import {YargsError} from "./index.js"; type ProposerConfig = ValidatorProposerConfig["defaultConfig"]; @@ -20,6 +21,7 @@ type ProposerConfigFileSection = { // for js-yaml gas_limit?: number; selection?: routes.validator.BuilderSelection; + boost_factor?: bigint; }; }; @@ -57,7 +59,7 @@ function parseProposerConfigSection( overrideConfig?: ProposerConfig ): ProposerConfig { const {graffiti, strict_fee_recipient_check, fee_recipient, builder} = proposerFileSection; - const {gas_limit, selection: builderSelection} = builder || {}; + const {gas_limit, selection: builderSelection, boost_factor} = builder || {}; if (graffiti !== undefined && typeof graffiti !== "string") { throw Error("graffiti is not 'string"); @@ -79,6 +81,9 @@ function parseProposerConfigSection( throw Error("(Number.isNaN(Number(gas_limit)) 2"); } } + if (boost_factor !== undefined && typeof boost_factor !== "string") { + throw Error("boost_factor is not 'string"); + } return { graffiti: overrideConfig?.graffiti ?? graffiti, @@ -88,7 +93,8 @@ function parseProposerConfigSection( feeRecipient: overrideConfig?.feeRecipient ?? (fee_recipient ? parseFeeRecipient(fee_recipient) : undefined), builder: { gasLimit: overrideConfig?.builder?.gasLimit ?? (gas_limit !== undefined ? Number(gas_limit) : undefined), - selection: overrideConfig?.builder?.selection ?? builderSelection, + selection: overrideConfig?.builder?.selection ?? parseBuilderSelection(builderSelection), + boostFactor: overrideConfig?.builder?.boostFactor ?? parseBuilderBoostFactor(boost_factor), }, }; } @@ -98,3 +104,31 @@ export function readProposerConfigDir(filepath: string, filename: string): Propo const proposerConfigJSON = JSON.parse(proposerConfigStr) as ProposerConfigFileSection; return proposerConfigJSON; } + +export function parseBuilderSelection(builderSelection?: string): routes.validator.BuilderSelection | undefined { + if (builderSelection) { + switch (builderSelection) { + case "maxprofit": + break; + case "builderalways": + break; + case "builderonly": + break; + case "executiononly": + break; + default: + throw new YargsError("Invalid input for builder selection, check help"); + } + } + return builderSelection as routes.validator.BuilderSelection; +} + +export function parseBuilderBoostFactor(boostFactor?: string): bigint | undefined { + if (boostFactor === undefined) return; + + if (!/^\d+$/.test(boostFactor)) { + throw new YargsError("Invalid input for builder boost factor, must be a valid number without decimals"); + } + + return BigInt(boostFactor); +} diff --git a/packages/cli/test/unit/validator/parseProposerConfig.test.ts b/packages/cli/test/unit/validator/parseProposerConfig.test.ts index fcb6933f035b..993d9640e47c 100644 --- a/packages/cli/test/unit/validator/parseProposerConfig.test.ts +++ b/packages/cli/test/unit/validator/parseProposerConfig.test.ts @@ -17,6 +17,7 @@ const testValue = { builder: { gasLimit: 30000000, selection: undefined, + boostFactor: undefined, }, }, "0xa4855c83d868f772a579133d9f23818008417b743e8447e235d8eb78b1d8f8a9f63f98c551beb7de254400f89592314d": { @@ -26,6 +27,7 @@ const testValue = { builder: { gasLimit: 35000000, selection: routes.validator.BuilderSelection.MaxProfit, + boostFactor: BigInt(18446744073709551616), }, }, }, @@ -36,6 +38,7 @@ const testValue = { builder: { gasLimit: 30000000, selection: routes.validator.BuilderSelection.BuilderAlways, + boostFactor: BigInt(100), }, }, }; diff --git a/packages/cli/test/unit/validator/proposerConfigs/validData.yaml b/packages/cli/test/unit/validator/proposerConfigs/validData.yaml index 6b7e7074b118..5ea7e1bebea7 100644 --- a/packages/cli/test/unit/validator/proposerConfigs/validData.yaml +++ b/packages/cli/test/unit/validator/proposerConfigs/validData.yaml @@ -10,6 +10,7 @@ proposer_config: builder: gas_limit: "35000000" selection: "maxprofit" + boost_factor: "18446744073709551616" default_config: graffiti: 'default graffiti' strict_fee_recipient_check: "true" @@ -17,3 +18,4 @@ default_config: builder: gas_limit: "30000000" selection: "builderalways" + boost_factor: "100" From 6adbd27c85f6fbb3a2a17ef4552274e985319c02 Mon Sep 17 00:00:00 2001 From: g11tech Date: Sat, 27 Jan 2024 22:37:49 +0530 Subject: [PATCH 10/41] fix: ignore forkchoice invalidations if latestValidHash not found (#6361) * fix: ignore forkchoice invalidations if latestValidHash not found * rename for better understanding * update the lvh search start index * apply feedback --- .../blocks/verifyBlocksExecutionPayloads.ts | 4 +- .../fork-choice/src/protoArray/interface.ts | 2 +- .../fork-choice/src/protoArray/protoArray.ts | 45 ++++++++++--------- .../protoArray/executionStatusUpdates.test.ts | 10 ++--- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts b/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts index 5dbe104c9541..91242d879f85 100644 --- a/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts +++ b/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts @@ -319,7 +319,7 @@ export async function verifyBlockExecutionPayload( const lvhResponse = { executionStatus, latestValidExecHash: execResult.latestValidHash, - invalidateFromBlockHash: toHexString(block.message.parentRoot), + invalidateFromParentBlockRoot: toHexString(block.message.parentRoot), }; const execError = new BlockError(block, { code: BlockErrorCode.EXECUTION_ENGINE_ERROR, @@ -416,7 +416,7 @@ function getSegmentErrorResponse( invalidSegmentLVH = { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: lvhResponse.latestValidExecHash, - invalidateFromBlockHash: parentBlock.blockRoot, + invalidateFromParentBlockRoot: parentBlock.blockRoot, }; } } diff --git a/packages/fork-choice/src/protoArray/interface.ts b/packages/fork-choice/src/protoArray/interface.ts index 1910ad2b4206..003a3c8f9f1e 100644 --- a/packages/fork-choice/src/protoArray/interface.ts +++ b/packages/fork-choice/src/protoArray/interface.ts @@ -29,7 +29,7 @@ export type LVHValidResponse = { export type LVHInvalidResponse = { executionStatus: ExecutionStatus.Invalid; latestValidExecHash: RootHex | null; - invalidateFromBlockHash: RootHex; + invalidateFromParentBlockRoot: RootHex; }; export type LVHExecResponse = LVHValidResponse | LVHInvalidResponse; diff --git a/packages/fork-choice/src/protoArray/protoArray.ts b/packages/fork-choice/src/protoArray/protoArray.ts index 62f50b03771c..eaa86b2f0ee1 100644 --- a/packages/fork-choice/src/protoArray/protoArray.ts +++ b/packages/fork-choice/src/protoArray/protoArray.ts @@ -279,32 +279,33 @@ export class ProtoArray { // Mark chain ii) as Invalid if LVH is found and non null, else only invalidate invalid_payload // if its in fcU. // - const {invalidateFromBlockHash, latestValidExecHash} = execResponse; - const invalidateFromIndex = this.indices.get(invalidateFromBlockHash); - if (invalidateFromIndex === undefined) { - throw Error(`Unable to find invalidateFromBlockHash=${invalidateFromBlockHash} in forkChoice`); + const {invalidateFromParentBlockRoot, latestValidExecHash} = execResponse; + const invalidateFromParentIndex = this.indices.get(invalidateFromParentBlockRoot); + if (invalidateFromParentIndex === undefined) { + throw Error(`Unable to find invalidateFromParentBlockRoot=${invalidateFromParentBlockRoot} in forkChoice`); } const latestValidHashIndex = - latestValidExecHash !== null ? this.getNodeIndexFromLVH(latestValidExecHash, invalidateFromIndex) : null; + latestValidExecHash !== null ? this.getNodeIndexFromLVH(latestValidExecHash, invalidateFromParentIndex) : null; if (latestValidHashIndex === null) { /** - * If the LVH is null or not found, represented with latestValidHashIndex=undefined, - * then just invalidate the invalid_payload and bug out. + * The LVH (latest valid hash) is null or not found. * - * Ideally in not found scenario we should invalidate the entire chain upwards, but - * it is possible (and observed in the testnets) that the EL was + * The spec gives an allowance for the EL being able to return a nullish LVH if it could not + * "determine" one. There are two interpretations: * - * i) buggy: that the LVH was not really the parent of the invalid block, but on - * some side chain - * ii) lazy: that invalidation was result of simple check and the EL just - * responded with a bogus LVH + * - "the LVH is unknown" - simply throw and move on. We can't determine which chain to invalidate + * since we don't know which ancestor is valid. * - * So we will just invalidate the current payload and let future responses take care - * to be as robust as possible. + * - "the LVH doesn't exist" - this means that the entire ancestor chain is invalid, and should + * be marked as such. + * + * The more robust approach is to treat nullish LVH as "the LVH is unknown" rather than + * "the LVH doesn't exist". The alternative means that we will poison a valid chain when the + * EL is lazy (or buggy) with its LVH response. */ - this.invalidateNodeByIndex(invalidateFromIndex); + throw Error(`Unable to find latestValidExecHash=${latestValidExecHash} in the forkchoice`); } else { - this.propagateInValidExecutionStatusByIndex(invalidateFromIndex, latestValidHashIndex, currentSlot); + this.propagateInValidExecutionStatusByIndex(invalidateFromParentIndex, latestValidHashIndex, currentSlot); } } } @@ -333,12 +334,12 @@ export class ProtoArray { */ private propagateInValidExecutionStatusByIndex( - invalidateFromIndex: number, + invalidateFromParentIndex: number, latestValidHashIndex: number, currentSlot: Slot ): void { - // Pass 1: mark invalidateFromIndex and its parents invalid - let invalidateIndex: number | undefined = invalidateFromIndex; + // Pass 1: mark invalidateFromParentIndex and its parents invalid + let invalidateIndex: number | undefined = invalidateFromParentIndex; while (invalidateIndex !== undefined && invalidateIndex > latestValidHashIndex) { const invalidNode = this.invalidateNodeByIndex(invalidateIndex); invalidateIndex = invalidNode.parent; @@ -368,8 +369,8 @@ export class ProtoArray { }); } - private getNodeIndexFromLVH(latestValidExecHash: RootHex, ancestorOfIndex: number): number | null { - let nodeIndex = this.nodes[ancestorOfIndex].parent; + private getNodeIndexFromLVH(latestValidExecHash: RootHex, ancestorFromIndex: number): number | null { + let nodeIndex: number | undefined = ancestorFromIndex; while (nodeIndex !== undefined && nodeIndex >= 0) { const node = this.getNodeFromIndex(nodeIndex); if ( diff --git a/packages/fork-choice/test/unit/protoArray/executionStatusUpdates.test.ts b/packages/fork-choice/test/unit/protoArray/executionStatusUpdates.test.ts index 94e5cd3ac9a0..e6916f24800f 100644 --- a/packages/fork-choice/test/unit/protoArray/executionStatusUpdates.test.ts +++ b/packages/fork-choice/test/unit/protoArray/executionStatusUpdates.test.ts @@ -149,7 +149,7 @@ describe("executionStatus / normal updates", () => { { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "2C", - invalidateFromBlockHash: "3C", + invalidateFromParentBlockRoot: "3C", }, 3 ); @@ -212,7 +212,7 @@ describe("executionStatus / normal updates", () => { { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "1A", - invalidateFromBlockHash: "3A", + invalidateFromParentBlockRoot: "3A", }, 3 ); @@ -259,7 +259,7 @@ describe("executionStatus / invalidate all postmerge chain", () => { { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - invalidateFromBlockHash: "3B", + invalidateFromParentBlockRoot: "3B", }, 3 ); @@ -336,7 +336,7 @@ describe("executionStatus / poision forkchoice if we invalidate previous valid", { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - invalidateFromBlockHash: "3A", + invalidateFromParentBlockRoot: "3A", }, 3 ) @@ -373,7 +373,7 @@ describe("executionStatus / poision forkchoice if we validate previous invalid", { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - invalidateFromBlockHash: "3B", + invalidateFromParentBlockRoot: "3B", }, 3 ); From 291e17867becb3884fe502542bcede5bae1fc5b1 Mon Sep 17 00:00:00 2001 From: Matthew Keil Date: Mon, 29 Jan 2024 01:55:48 -0500 Subject: [PATCH 11/41] feat: add down-scoring for metadata ssz size error (#6366) --- packages/beacon-node/src/network/reqresp/score.ts | 1 + packages/reqresp/src/request/errors.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/beacon-node/src/network/reqresp/score.ts b/packages/beacon-node/src/network/reqresp/score.ts index 6aca573a9ca9..c74b645c9909 100644 --- a/packages/beacon-node/src/network/reqresp/score.ts +++ b/packages/beacon-node/src/network/reqresp/score.ts @@ -24,6 +24,7 @@ export function onOutgoingReqRespError(e: RequestError, method: ReqRespMethod): switch (e.type.code) { case RequestErrorCode.INVALID_REQUEST: case RequestErrorCode.INVALID_RESPONSE_SSZ: + case RequestErrorCode.SSZ_OVER_MAX_SIZE: return PeerAction.LowToleranceError; case RequestErrorCode.SERVER_ERROR: diff --git a/packages/reqresp/src/request/errors.ts b/packages/reqresp/src/request/errors.ts index ccc3c12f97a1..0078ad5d2ecf 100644 --- a/packages/reqresp/src/request/errors.ts +++ b/packages/reqresp/src/request/errors.ts @@ -31,6 +31,8 @@ export enum RequestErrorCode { RESP_TIMEOUT = "REQUEST_ERROR_RESP_TIMEOUT", /** Request rate limited */ REQUEST_RATE_LIMITED = "REQUEST_ERROR_RATE_LIMITED", + /** */ + SSZ_OVER_MAX_SIZE = "SSZ_SNAPPY_ERROR_OVER_SSZ_MAX_SIZE", } type RequestErrorType = @@ -47,7 +49,8 @@ type RequestErrorType = | {code: RequestErrorCode.EMPTY_RESPONSE} | {code: RequestErrorCode.TTFB_TIMEOUT} | {code: RequestErrorCode.RESP_TIMEOUT} - | {code: RequestErrorCode.REQUEST_RATE_LIMITED}; + | {code: RequestErrorCode.REQUEST_RATE_LIMITED} + | {code: RequestErrorCode.SSZ_OVER_MAX_SIZE}; export const REQUEST_ERROR_CLASS_NAME = "RequestError"; From cbf349c73d7730c11d7295c27a61fbf36225df52 Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 29 Jan 2024 00:53:35 -0800 Subject: [PATCH 12/41] feat: blob sidecars can be filtered by indices (#6337) * feat: blob sidecars can be filtered by indices * fix: properly filter blobs * fix: type indices as number * chore: remove use of set * fix: make stringify more robust * Update packages/beacon-node/src/api/impl/beacon/blocks/index.ts Co-authored-by: Nico Flaig * fix: cleanup * fix: remove useless types --------- Co-authored-by: Nico Flaig --- .../api/src/beacon/routes/beacon/block.ts | 19 ++++++++++++++++--- .../api/test/unit/beacon/oapiSpec.test.ts | 6 ------ .../api/test/unit/beacon/testData/beacon.ts | 2 +- packages/api/test/utils/checkAgainstSpec.ts | 15 ++++++++++++--- .../src/api/impl/beacon/blocks/index.ts | 5 +++-- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/packages/api/src/beacon/routes/beacon/block.ts b/packages/api/src/beacon/routes/beacon/block.ts index 95a32097028d..c1f1e723e358 100644 --- a/packages/api/src/beacon/routes/beacon/block.ts +++ b/packages/api/src/beacon/routes/beacon/block.ts @@ -229,8 +229,12 @@ export type Api = { * Retrieves BlobSidecar included in requested block. * @param blockId Block identifier. * Can be one of: "head" (canonical head in node's view), "genesis", "finalized", \, \. + * @param indices Array of indices for blob sidecars to request for in the specified block. Returns all blob sidecars in the block if not specified. */ - getBlobSidecars(blockId: BlockId): Promise< + getBlobSidecars( + blockId: BlockId, + indices?: number[] + ): Promise< ApiClientResponse<{ [HttpStatusCode.OK]: {executionOptimistic: ExecutionOptimistic; data: deneb.BlobSidecars}; }> @@ -270,7 +274,7 @@ export type ReqTypes = { publishBlockV2: {body: unknown; query: {broadcast_validation?: string}}; publishBlindedBlock: {body: unknown}; publishBlindedBlockV2: {body: unknown; query: {broadcast_validation?: string}}; - getBlobSidecars: BlockIdOnlyReq; + getBlobSidecars: {params: {block_id: string}; query: {indices?: number[]}}; }; export function getReqSerializers(config: ChainForkConfig): ReqSerializers { @@ -356,7 +360,16 @@ export function getReqSerializers(config: ChainForkConfig): ReqSerializers ({ + params: {block_id: String(block_id)}, + query: {indices}, + }), + parseReq: ({params, query}) => [params.block_id, query.indices], + schema: { + query: {indices: Schema.UintArray}, + }, + }, }; } diff --git a/packages/api/test/unit/beacon/oapiSpec.test.ts b/packages/api/test/unit/beacon/oapiSpec.test.ts index 15a10bfeb6f7..f7d6cb9a077c 100644 --- a/packages/api/test/unit/beacon/oapiSpec.test.ts +++ b/packages/api/test/unit/beacon/oapiSpec.test.ts @@ -130,12 +130,6 @@ const ignoredProperties: Record = { */ getHealth: {request: ["query.syncing_status"]}, - /** - * https://github.com/ChainSafe/lodestar/issues/6185 - * - must have required property 'query' - */ - getBlobSidecars: {request: ["query"]}, - /* https://github.com/ChainSafe/lodestar/issues/4638 /query - must have required property 'skip_randao_verification' diff --git a/packages/api/test/unit/beacon/testData/beacon.ts b/packages/api/test/unit/beacon/testData/beacon.ts index 7fa8368c590b..6d6bc6576f56 100644 --- a/packages/api/test/unit/beacon/testData/beacon.ts +++ b/packages/api/test/unit/beacon/testData/beacon.ts @@ -71,7 +71,7 @@ export const testData: GenericServerTestCases = { res: undefined, }, getBlobSidecars: { - args: ["head"], + args: ["head", [0]], res: {executionOptimistic: true, data: ssz.deneb.BlobSidecars.defaultValue()}, }, diff --git a/packages/api/test/utils/checkAgainstSpec.ts b/packages/api/test/utils/checkAgainstSpec.ts index ed65279bca22..c887f66e95e6 100644 --- a/packages/api/test/utils/checkAgainstSpec.ts +++ b/packages/api/test/utils/checkAgainstSpec.ts @@ -199,12 +199,21 @@ function prettyAjvErrors(errors: ErrorObject[] | null | undefined): string { return errors.map((e) => `${e.instancePath ?? "."} - ${e.message}`).join("\n"); } +type StringifiedProperty = string | StringifiedProperty[]; + +function stringifyProperty(value: unknown): StringifiedProperty { + if (typeof value === "number") { + return value.toString(10); + } else if (Array.isArray(value)) { + return value.map(stringifyProperty); + } + return String(value); +} + function stringifyProperties(obj: Record): Record { for (const key of Object.keys(obj)) { const value = obj[key]; - if (typeof value === "number") { - obj[key] = value.toString(10); - } + obj[key] = stringifyProperty(value); } return obj; 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 f2e29f00fe57..6fde04bc737c 100644 --- a/packages/beacon-node/src/api/impl/beacon/blocks/index.ts +++ b/packages/beacon-node/src/api/impl/beacon/blocks/index.ts @@ -406,7 +406,7 @@ export function getBeaconBlockApi({ await publishBlock(signedBlockOrContents, opts); }, - async getBlobSidecars(blockId) { + async getBlobSidecars(blockId, indices) { const {block, executionOptimistic} = await resolveBlockId(chain, blockId); const blockRoot = config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message); @@ -418,9 +418,10 @@ export function getBeaconBlockApi({ if (!blobSidecars) { throw Error(`blobSidecars not found in db for slot=${block.message.slot} root=${toHexString(blockRoot)}`); } + return { executionOptimistic, - data: blobSidecars, + data: indices ? blobSidecars.filter(({index}) => indices.includes(index)) : blobSidecars, }; }, }; From 54c20699d2395ba0ac658616b8a227fc52ccc414 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Mon, 29 Jan 2024 18:15:27 +0100 Subject: [PATCH 13/41] fix: ignore stale keystore lockfiles (#6363) * fix: ignore stale keystore lockfiles * Update error message if lockfile is already acquired * Update keymanager lockfile e2e tests --- packages/cli/package.json | 4 +- packages/cli/src/util/lockfile.ts | 54 +++++++++++-------- .../test/e2e/importKeystoresFromApi.test.ts | 8 +-- .../decryptKeystoreDefinitions.test.ts | 13 +++-- packages/db/src/controller/level.ts | 2 +- yarn.lock | 19 +++---- 6 files changed, 55 insertions(+), 45 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index c16baf13c25f..8531db5b633f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -77,7 +77,6 @@ "@lodestar/utils": "^1.15.0", "@lodestar/validator": "^1.15.0", "@multiformats/multiaddr": "^12.1.3", - "@types/lockfile": "^1.0.2", "bip39": "^3.1.0", "deepmerge": "^4.3.1", "ethers": "^6.7.0", @@ -86,9 +85,9 @@ "got": "^11.8.6", "inquirer": "^9.1.5", "js-yaml": "^4.1.0", - "lockfile": "^1.0.4", "lodash": "^4.17.21", "prom-client": "^15.1.0", + "proper-lockfile": "^4.1.2", "rimraf": "^4.4.1", "source-map-support": "^0.5.21", "uint8arrays": "^4.0.9", @@ -102,6 +101,7 @@ "@types/got": "^9.6.12", "@types/inquirer": "^9.0.3", "@types/lodash": "^4.14.192", + "@types/proper-lockfile": "^4.1.4", "@types/yargs": "^17.0.24" } } diff --git a/packages/cli/src/util/lockfile.ts b/packages/cli/src/util/lockfile.ts index 65933e8f2897..f7a6ddf4d57d 100644 --- a/packages/cli/src/util/lockfile.ts +++ b/packages/cli/src/util/lockfile.ts @@ -1,29 +1,21 @@ -export type Lockfile = { - lockSync(path: string): void; - unlockSync(path: string): void; -}; - -const lockFile: Lockfile = (await import("lockfile")) as Lockfile; - -function getLockFilepath(filepath: string): string { - return `${filepath}.lock`; -} - -/** - * When lockfile is imported, it registers listeners to process - * Since it's only used by the validator client, require lazily to not pollute - * beacon_node client context - */ -function getLockFile(): Lockfile { - return lockFile; -} +import {lockSync, unlockSync} from "proper-lockfile"; /** * Creates a .lock file for `filepath`, argument passed must not be the lock path * @param filepath File to lock, i.e. `keystore_0001.json` */ export function lockFilepath(filepath: string): void { - getLockFile().lockSync(getLockFilepath(filepath)); + try { + lockSync(filepath, { + // Allows to lock files that do not exist + realpath: false, + }); + } catch (e) { + if (isLockfileError(e) && e.code === "ELOCKED") { + e.message = `${filepath} is already in use by another process`; + } + throw e; + } } /** @@ -31,7 +23,23 @@ export function lockFilepath(filepath: string): void { * @param filepath File to unlock, i.e. `keystore_0001.json` */ export function unlockFilepath(filepath: string): void { - // Does not throw if the lock file is already deleted - // https://github.com/npm/lockfile/blob/6590779867ee9bdc5dbebddc962640759892bb91/lockfile.js#L68 - getLockFile().unlockSync(getLockFilepath(filepath)); + try { + unlockSync(filepath, { + // Allows to unlock files that do not exist + realpath: false, + }); + } catch (e) { + if (isLockfileError(e) && e.code === "ENOTACQUIRED") { + // Do not throw if the lock file is already deleted + return; + } + throw e; + } +} + +// https://github.com/moxystudio/node-proper-lockfile/blob/9f8c303c91998e8404a911dc11c54029812bca69/lib/lockfile.js#L53 +export type LockfileError = Error & {code: "ELOCKED" | "ENOTACQUIRED"}; + +function isLockfileError(e: unknown): e is LockfileError { + return e instanceof Error && (e as LockfileError).code !== undefined; } diff --git a/packages/cli/test/e2e/importKeystoresFromApi.test.ts b/packages/cli/test/e2e/importKeystoresFromApi.test.ts index bb91d467b86a..1cf5f107e226 100644 --- a/packages/cli/test/e2e/importKeystoresFromApi.test.ts +++ b/packages/cli/test/e2e/importKeystoresFromApi.test.ts @@ -95,10 +95,10 @@ describe("import keystores from api", function () { validator.on("exit", (code) => { if (code !== null && code > 0) { // process should exit with code > 0, and an error related to locks. Sample error: - // vc 351591: ✖ Error: EEXIST: file already exists, open '/tmp/tmp-351554-dMctEAj7sJIz/import-keystores-test/keystores/0x8be678633e927aa0435addad5dcd5283fef6110d91362519cd6d43e61f6c017d724fa579cc4b2972134e050b6ba120c0/voting-keystore.json.lock' - // at Object.openSync (node:fs:585:3) - // at Module.exports.lockSync (/home/lion/Code/eth2.0/lodestar/node_modules/lockfile/lockfile.js:277:17) - if (/EEXIST.*voting-keystore\.json\.lock/.test(vcProc2Stderr.read())) { + // vc 351591: ✖ Error: /tmp/tmp-5080-lwNxdM5Ok9ya/import-keystores-test/keystores/0x8be678633e927aa0435addad5dcd5283fef6110d91362519cd6d43e61f6c017d724fa579cc4b2972134e050b6ba120c0/voting-keystore.json is already in use by another process + // at /home/runner/actions-runner/_work/lodestar/lodestar/node_modules/proper-lockfile/lib/lockfile.js:68:47 + // ... more stack trace + if (/Error.*voting-keystore\.json is already in use by another process/.test(vcProc2Stderr.read())) { resolve(); } else { reject(Error(`Second validator proc exited with unknown error. stderr:\n${vcProc2Stderr.read()}`)); diff --git a/packages/cli/test/unit/validator/decryptKeystoreDefinitions.test.ts b/packages/cli/test/unit/validator/decryptKeystoreDefinitions.test.ts index f24b83ae43a6..0f4173604405 100644 --- a/packages/cli/test/unit/validator/decryptKeystoreDefinitions.test.ts +++ b/packages/cli/test/unit/validator/decryptKeystoreDefinitions.test.ts @@ -7,6 +7,7 @@ import {cachedSeckeysHex} from "../../utils/cachedKeys.js"; import {testFilesDir} from "../../utils.js"; import {decryptKeystoreDefinitions} from "../../../src/cmds/validator/keymanager/decryptKeystoreDefinitions.js"; import {LocalKeystoreDefinition} from "../../../src/cmds/validator/keymanager/interface.js"; +import {LockfileError, unlockFilepath} from "../../../src/util/lockfile.js"; describe("decryptKeystoreDefinitions", () => { vi.setConfig({testTimeout: 100_000}); @@ -22,6 +23,10 @@ describe("decryptKeystoreDefinitions", () => { let definitions: LocalKeystoreDefinition[] = []; beforeEach(async () => { + // remove lockfiles from proper-lockfile cache + for (const {keystorePath} of definitions) { + unlockFilepath(keystorePath); + } rimraf.sync(dataDir); rimraf.sync(importFromDir); @@ -46,7 +51,9 @@ describe("decryptKeystoreDefinitions", () => { expect(fs.existsSync(cacheFilePath)).toBe(true); // remove lockfiles created during cache file preparation - rimraf.sync(path.join(importFromDir, "*.lock"), {glob: true}); + for (const {keystorePath} of definitions) { + unlockFilepath(keystorePath); + } }); testDecryptKeystoreDefinitions(cacheFilePath); @@ -75,14 +82,14 @@ describe("decryptKeystoreDefinitions", () => { await decryptKeystoreDefinitions(definitions, {logger: console, signal, cacheFilePath}); expect.fail("Second decrypt should fail due to failure to get lockfile"); } catch (e) { - expect((e as Error).message.startsWith("EEXIST: file already exists")).toBe(true); + expect((e as LockfileError).code).toBe("ELOCKED"); } }); it("decrypt keystores if lockfiles already exist if ignoreLockFile=true", async () => { await decryptKeystoreDefinitions(definitions, {logger: console, signal, cacheFilePath}); - // lockfiles should exist after the first run + await decryptKeystoreDefinitions(definitions, {logger: console, signal, cacheFilePath, ignoreLockFile: true}); }); } diff --git a/packages/db/src/controller/level.ts b/packages/db/src/controller/level.ts index 3eed75958e3e..2cea8681c95b 100644 --- a/packages/db/src/controller/level.ts +++ b/packages/db/src/controller/level.ts @@ -52,7 +52,7 @@ export class LevelDbController implements DatabaseController Date: Tue, 30 Jan 2024 00:17:23 +0700 Subject: [PATCH 14/41] fix: stabilize unknown block sync e2e test (#6364) fix: stabalize unknown block sync e2e test --- .../test/e2e/sync/unknownBlockSync.test.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts index a51beaf7b961..e64adfc94888 100644 --- a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts +++ b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts @@ -12,7 +12,7 @@ import {waitForEvent} from "../../utils/events/resolver.js"; import {getAndInitDevValidators} from "../../utils/node/validator.js"; import {ChainEvent} from "../../../src/chain/index.js"; import {NetworkEvent} from "../../../src/network/index.js"; -import {connect} from "../../utils/network.js"; +import {connect, onPeerConnect} from "../../utils/network.js"; 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"; @@ -48,7 +48,7 @@ describe("sync / unknown block sync", function () { for (const {id, event} of testCases) { it(id, async function () { // the node needs time to transpile/initialize bls worker threads - const genesisSlotsDelay = 7; + const genesisSlotsDelay = 4; const genesisTime = Math.floor(Date.now() / 1000) + genesisSlotsDelay * testParams.SECONDS_PER_SLOT; const testLoggerOpts: TestLoggerOpts = { level: LogLevel.info, @@ -71,6 +71,7 @@ describe("sync / unknown block sync", function () { chain: {blsVerifyAllMainThread: true}, }, validatorCount, + genesisTime, logger: loggerNodeA, }); @@ -100,7 +101,7 @@ describe("sync / unknown block sync", function () { chain: {blsVerifyAllMainThread: true}, }, validatorCount, - genesisTime: bn.chain.getHeadState().genesisTime, + genesisTime, logger: loggerNodeB, }); @@ -116,7 +117,11 @@ describe("sync / unknown block sync", function () { ({block}) => block === headSummary.blockRoot ); + const connected = Promise.all([onPeerConnect(bn2.network), onPeerConnect(bn.network)]); await connect(bn2.network, bn.network); + await connected; + loggerNodeA.info("Node A connected to Node B"); + const headInput = getBlockInput.preDeneb(config, head, BlockSource.gossip, null); switch (event) { @@ -147,4 +152,4 @@ describe("sync / unknown block sync", function () { await waitForSynced; }); } -}, {timeout: 30_000}); +}, {timeout: 40_000}); From ed43a988bf7acbe25fad9988434a1ade3ed6016e Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 29 Jan 2024 09:53:35 -0800 Subject: [PATCH 15/41] chore: align vitest config filenames (#6369) --- CONTRIBUTING.md | 2 +- packages/beacon-node/package.json | 10 +++++----- .../{vitest.config.e2e.ts => vitest.e2e.config.ts} | 0 .../{vitest.config.spec.ts => vitest.spec.config.ts} | 0 packages/cli/package.json | 2 +- .../cli/{vitest.config.e2e.ts => vitest.e2e.config.ts} | 0 packages/logger/package.json | 2 +- .../{vitest.config.e2e.ts => vitest.e2e.config.ts} | 0 packages/params/package.json | 2 +- .../{vitest.config.e2e.ts => vitest.e2e.config.ts} | 0 packages/prover/package.json | 2 +- .../{vitest.config.e2e.ts => vitest.e2e.config.ts} | 0 packages/spec-test-util/package.json | 2 +- .../{vitest.config.e2e.ts => vitest.e2e.config.ts} | 0 packages/validator/package.json | 4 ++-- .../{vitest.config.e2e.ts => vitest.e2e.config.ts} | 0 .../{vitest.config.spec.ts => vitest.spec.config.ts} | 0 17 files changed, 13 insertions(+), 13 deletions(-) rename packages/beacon-node/{vitest.config.e2e.ts => vitest.e2e.config.ts} (100%) rename packages/beacon-node/{vitest.config.spec.ts => vitest.spec.config.ts} (100%) rename packages/cli/{vitest.config.e2e.ts => vitest.e2e.config.ts} (100%) rename packages/logger/{vitest.config.e2e.ts => vitest.e2e.config.ts} (100%) rename packages/params/{vitest.config.e2e.ts => vitest.e2e.config.ts} (100%) rename packages/prover/{vitest.config.e2e.ts => vitest.e2e.config.ts} (100%) rename packages/spec-test-util/{vitest.config.e2e.ts => vitest.e2e.config.ts} (100%) rename packages/validator/{vitest.config.e2e.ts => vitest.e2e.config.ts} (100%) rename packages/validator/{vitest.config.spec.ts => vitest.spec.config.ts} (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4074c47e88e8..75fc18a95da9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,7 @@ If you observe following error running any of the test files that means you are - To then run only that failed test you can run against a specific file as use vitest's filters to run only one case ```sh -LODESTAR_PRESET=minimal yarn vitest --run --config vitest.config.spec.ts test/spec/phase0/sanity.test.ts +LODESTAR_PRESET=minimal yarn vitest --run --config vitest.spec.config.ts test/spec/phase0/sanity.test.ts ``` ## Docker diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index aab75c458d56..174ed8cbb125 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -79,17 +79,17 @@ "test:unit:minimal": "vitest --run --segfaultRetry 3 --dir test/unit/", "test:unit:mainnet": "LODESTAR_PRESET=mainnet vitest --run --dir test/unit-mainnet", "test:unit": "wrapper() { yarn test:unit:minimal $@ && yarn test:unit:mainnet $@; }; wrapper", - "test:e2e": "LODESTAR_PRESET=minimal vitest --run --segfaultRetry 3 --config vitest.config.e2e.ts --dir test/e2e", + "test:e2e": "LODESTAR_PRESET=minimal vitest --run --segfaultRetry 3 --config vitest.e2e.config.ts --dir test/e2e", "test:sim": "vitest --run test/sim/**/*.test.ts", "test:sim:merge-interop": "vitest --run test/sim/merge-interop.test.ts", "test:sim:mergemock": "vitest --run test/sim/mergemock.test.ts", "test:sim:withdrawals": "vitest --run test/sim/withdrawal-interop.test.ts", "test:sim:blobs": "vitest --run test/sim/4844-interop.test.ts", "download-spec-tests": "node --loader=ts-node/esm test/spec/downloadTests.ts", - "test:spec:bls": "vitest --run --config vitest.config.spec.ts --dir test/spec/bls/", - "test:spec:general": "vitest --run --config vitest.config.spec.ts --dir test/spec/general/", - "test:spec:minimal": "LODESTAR_PRESET=minimal vitest --run --config vitest.config.spec.ts --dir test/spec/presets/", - "test:spec:mainnet": "LODESTAR_PRESET=mainnet vitest --run --config vitest.config.spec.ts --dir test/spec/presets/", + "test:spec:bls": "vitest --run --config vitest.spec.config.ts --dir test/spec/bls/", + "test:spec:general": "vitest --run --config vitest.spec.config.ts --dir test/spec/general/", + "test:spec:minimal": "LODESTAR_PRESET=minimal vitest --run --config vitest.spec.config.ts --dir test/spec/presets/", + "test:spec:mainnet": "LODESTAR_PRESET=mainnet vitest --run --config vitest.spec.config.ts --dir test/spec/presets/", "test:spec": "yarn test:spec:bls && yarn test:spec:general && yarn test:spec:minimal && yarn test:spec:mainnet", "check-readme": "typescript-docs-verifier" }, diff --git a/packages/beacon-node/vitest.config.e2e.ts b/packages/beacon-node/vitest.e2e.config.ts similarity index 100% rename from packages/beacon-node/vitest.config.e2e.ts rename to packages/beacon-node/vitest.e2e.config.ts diff --git a/packages/beacon-node/vitest.config.spec.ts b/packages/beacon-node/vitest.spec.config.ts similarity index 100% rename from packages/beacon-node/vitest.config.spec.ts rename to packages/beacon-node/vitest.spec.config.ts diff --git a/packages/cli/package.json b/packages/cli/package.json index 8531db5b633f..d21e523696ef 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -31,7 +31,7 @@ "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", "test:unit": "vitest --run --dir test/unit/", - "test:e2e": "vitest --run --config vitest.config.e2e.ts --dir test/e2e/", + "test:e2e": "vitest --run --config vitest.e2e.config.ts --dir test/e2e/", "test:sim:multifork": "LODESTAR_PRESET=minimal node --loader ts-node/esm test/sim/multi_fork.test.ts", "test:sim:mixedclient": "LODESTAR_PRESET=minimal node --loader ts-node/esm test/sim/mixed_client.test.ts", "test:sim:endpoints": "LODESTAR_PRESET=minimal node --loader ts-node/esm test/sim/endpoints.test.ts", diff --git a/packages/cli/vitest.config.e2e.ts b/packages/cli/vitest.e2e.config.ts similarity index 100% rename from packages/cli/vitest.config.e2e.ts rename to packages/cli/vitest.e2e.config.ts diff --git a/packages/logger/package.json b/packages/logger/package.json index fd82a7651b3f..e8d32622ae95 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -61,7 +61,7 @@ "test:browsers:chrome": "vitest --run --browser chrome --config ./vitest.browser.config.ts --dir test/unit", "test:browsers:firefox": "vitest --run --browser firefox --config ./vitest.browser.config.ts --dir test/unit", "test:browsers:electron": "echo 'Electron tests will be introduced back in the future as soon vitest supports electron.'", - "test:e2e": "LODESTAR_PRESET=minimal vitest --run --config vitest.config.e2e.ts --dir test/e2e", + "test:e2e": "LODESTAR_PRESET=minimal vitest --run --config vitest.e2e.config.ts --dir test/e2e", "check-readme": "typescript-docs-verifier" }, "types": "lib/index.d.ts", diff --git a/packages/logger/vitest.config.e2e.ts b/packages/logger/vitest.e2e.config.ts similarity index 100% rename from packages/logger/vitest.config.e2e.ts rename to packages/logger/vitest.e2e.config.ts diff --git a/packages/params/package.json b/packages/params/package.json index ebd4116f16b1..bd5259c4712d 100644 --- a/packages/params/package.json +++ b/packages/params/package.json @@ -58,7 +58,7 @@ "test:browsers:chrome": "vitest --run --browser chrome --config ./vitest.browser.config.ts --dir test/unit", "test:browsers:firefox": "vitest --run --browser firefox --config ./vitest.browser.config.ts --dir test/unit", "test:browsers:electron": "echo 'Electron tests will be introduced back in the future as soon vitest supports electron.'", - "test:e2e": "LODESTAR_PRESET=minimal vitest --run --config vitest.config.e2e.ts --dir test/e2e/", + "test:e2e": "LODESTAR_PRESET=minimal vitest --run --config vitest.e2e.config.ts --dir test/e2e/", "check-readme": "typescript-docs-verifier" }, "repository": { diff --git a/packages/params/vitest.config.e2e.ts b/packages/params/vitest.e2e.config.ts similarity index 100% rename from packages/params/vitest.config.e2e.ts rename to packages/params/vitest.e2e.config.ts diff --git a/packages/prover/package.json b/packages/prover/package.json index 36433fa8d567..b5c7eac31033 100644 --- a/packages/prover/package.json +++ b/packages/prover/package.json @@ -57,7 +57,7 @@ "test:browsers:chrome": "vitest --run --browser chrome --config ./vitest.browser.config.ts --dir test/unit", "test:browsers:firefox": "vitest --run --browser firefox --config ./vitest.browser.config.ts --dir test/unit", "test:browsers:electron": "echo 'Electron tests will be introduced back in the future as soon vitest supports electron.'", - "test:e2e": "LODESTAR_PRESET=minimal vitest --run --config vitest.config.e2e.ts --dir test/e2e", + "test:e2e": "LODESTAR_PRESET=minimal vitest --run --config vitest.e2e.config.ts --dir test/e2e", "check-readme": "typescript-docs-verifier", "generate-fixtures": "node --loader ts-node/esm scripts/generate_fixtures.ts" }, diff --git a/packages/prover/vitest.config.e2e.ts b/packages/prover/vitest.e2e.config.ts similarity index 100% rename from packages/prover/vitest.config.e2e.ts rename to packages/prover/vitest.e2e.config.ts diff --git a/packages/spec-test-util/package.json b/packages/spec-test-util/package.json index c2c202a72614..7e9a82b16035 100644 --- a/packages/spec-test-util/package.json +++ b/packages/spec-test-util/package.json @@ -48,7 +48,7 @@ "lint:fix": "yarn run lint --fix", "test": "yarn test:unit && yarn test:e2e", "test:unit": "vitest --run --passWithNoTests --dir test/unit/", - "test:e2e": "vitest --run --config vitest.config.e2e.ts --dir test/e2e/", + "test:e2e": "vitest --run --config vitest.e2e.config.ts --dir test/e2e/", "check-readme": "typescript-docs-verifier" }, "repository": { diff --git a/packages/spec-test-util/vitest.config.e2e.ts b/packages/spec-test-util/vitest.e2e.config.ts similarity index 100% rename from packages/spec-test-util/vitest.config.e2e.ts rename to packages/spec-test-util/vitest.e2e.config.ts diff --git a/packages/validator/package.json b/packages/validator/package.json index 5a2dcb55c2ba..5b913ad84a63 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -29,8 +29,8 @@ "lint:fix": "yarn run lint --fix", "test:unit": "vitest --run --dir test/unit/", "test": "yarn test:unit && yarn test:e2e", - "test:spec": "vitest --run --config vitest.config.spec.ts --dir test/spec/", - "test:e2e": "LODESTAR_PRESET=mainnet vitest --run --config vitest.config.e2e.ts --dir test/e2e", + "test:spec": "vitest --run --config vitest.spec.config.ts --dir test/spec/", + "test:e2e": "LODESTAR_PRESET=mainnet vitest --run --config vitest.e2e.config.ts --dir test/e2e", "download-spec-tests": "node --loader=ts-node/esm test/spec/downloadTests.ts", "coverage": "codecov -F lodestar-validator", "check-readme": "typescript-docs-verifier" diff --git a/packages/validator/vitest.config.e2e.ts b/packages/validator/vitest.e2e.config.ts similarity index 100% rename from packages/validator/vitest.config.e2e.ts rename to packages/validator/vitest.e2e.config.ts diff --git a/packages/validator/vitest.config.spec.ts b/packages/validator/vitest.spec.config.ts similarity index 100% rename from packages/validator/vitest.config.spec.ts rename to packages/validator/vitest.spec.config.ts From 8b354f2087cac8abea6f478b8bda6fe09ebdc528 Mon Sep 17 00:00:00 2001 From: Matthew Keil Date: Tue, 30 Jan 2024 16:17:20 +0700 Subject: [PATCH 16/41] docs: add comment to RequestErrorCode.SSZ_OVER_MAX_SIZE (#6373) --- packages/reqresp/src/request/errors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/reqresp/src/request/errors.ts b/packages/reqresp/src/request/errors.ts index 0078ad5d2ecf..ba3904e563ed 100644 --- a/packages/reqresp/src/request/errors.ts +++ b/packages/reqresp/src/request/errors.ts @@ -31,7 +31,7 @@ export enum RequestErrorCode { RESP_TIMEOUT = "REQUEST_ERROR_RESP_TIMEOUT", /** Request rate limited */ REQUEST_RATE_LIMITED = "REQUEST_ERROR_RATE_LIMITED", - /** */ + /** For malformed SSZ (metadata) responses */ SSZ_OVER_MAX_SIZE = "SSZ_SNAPPY_ERROR_OVER_SSZ_MAX_SIZE", } From 5064fab473641bb724425222db79646ac7016ae7 Mon Sep 17 00:00:00 2001 From: scott willeke Date: Tue, 30 Jan 2024 01:30:14 -0800 Subject: [PATCH 17/41] docs: update link to erigon jwt setup (#6375) --- docs/pages/getting-started/starting-a-node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/getting-started/starting-a-node.md b/docs/pages/getting-started/starting-a-node.md index dd11381bde10..665a39b0df80 100644 --- a/docs/pages/getting-started/starting-a-node.md +++ b/docs/pages/getting-started/starting-a-node.md @@ -47,7 +47,7 @@ Use the `--JsonRpc.JwtSecretFile /data/jwtsecret` flag to configure the secret. Use the `--engine-jwt-secret=` flag to configure the secret. Use their documentation [here](https://besu.hyperledger.org/en/stable/Reference/CLI/CLI-Syntax/#engine-jwt-secret). **For Erigon:** -Use the `--authrpc.jwtsecret` flag to configure the secret. Use their documentation [here](https://github.com/ledgerwatch/erigon#authentication-api). +Use the `--authrpc.jwtsecret` flag to configure the secret. Use their documentation [here](https://github.com/ledgerwatch/erigon?tab=readme-ov-file#beacon-chain-consensus-layer). ## Run a beacon node From b5344bfe59cf8b0b7d13ae4722fed2f463506b7b Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Tue, 30 Jan 2024 13:47:50 +0100 Subject: [PATCH 18/41] fix: add block_id schema validation to getBlobSidecars (#6377) --- packages/api/src/beacon/routes/beacon/block.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/api/src/beacon/routes/beacon/block.ts b/packages/api/src/beacon/routes/beacon/block.ts index c1f1e723e358..ae150ca6b3e8 100644 --- a/packages/api/src/beacon/routes/beacon/block.ts +++ b/packages/api/src/beacon/routes/beacon/block.ts @@ -367,6 +367,7 @@ export function getReqSerializers(config: ChainForkConfig): ReqSerializers [params.block_id, query.indices], schema: { + params: {block_id: Schema.StringRequired}, query: {indices: Schema.UintArray}, }, }, From f2e352ff017341e098b8dcea8bd8bd204a93c425 Mon Sep 17 00:00:00 2001 From: tuyennhv Date: Wed, 31 Jan 2024 05:54:13 +0700 Subject: [PATCH 19/41] fix: skip useWorker mode for gossipsub e2e tests (#6368) --- packages/beacon-node/test/e2e/network/gossipsub.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/beacon-node/test/e2e/network/gossipsub.test.ts b/packages/beacon-node/test/e2e/network/gossipsub.test.ts index 0ffab720598c..c7b3dbefbe77 100644 --- a/packages/beacon-node/test/e2e/network/gossipsub.test.ts +++ b/packages/beacon-node/test/e2e/network/gossipsub.test.ts @@ -16,7 +16,12 @@ describe( {timeout: 3000} ); -describe( +/** + * This is nice to have to investigate networking issue in local environment. + * 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 () { runTests({useWorker: true}); From 8e0078b828c57c1476a422e80d037306380ca512 Mon Sep 17 00:00:00 2001 From: Julien Date: Tue, 30 Jan 2024 14:54:37 -0800 Subject: [PATCH 20/41] docs: reflect vitest migration (#6247) * fix: reflect vitest migration * fix: incorrect spec example folder * chore: added filter examples --------- Co-authored-by: Cayman --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 75fc18a95da9..7e567ab517fc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,11 +61,12 @@ If you observe following error running any of the test files that means you are - To fix errors always focus on passing all minimal tests first without running mainnet tests. - Spec tests often compare full expected vs actual states in JSON format. -- A single logical error can cause many spec tests to fail. To focus on a single test at a time you can use vitest's option `--bail` to stop at the first failed test -- To then run only that failed test you can run against a specific file as use vitest's filters to run only one case +- A single logical error can cause many spec tests to fail. To focus on a single test at a time you can use vitest's option `--bail 1` to stop at the first failed test +- To then run only that failed test you can run against a specific file as use vitest's filters option `-t ` to run only one case ```sh -LODESTAR_PRESET=minimal yarn vitest --run --config vitest.spec.config.ts test/spec/phase0/sanity.test.ts +cd packages/beacon-node +LODESTAR_PRESET=minimal yarn vitest --run --bail 1 --config vitest.spec.config.ts test/spec/presets/sanity.test.ts -t attester_slashing ``` ## Docker From 6b732b0cf553e2b3b83b89307d761f2cdd84c201 Mon Sep 17 00:00:00 2001 From: Matthew Keil Date: Thu, 1 Feb 2024 15:34:56 +0700 Subject: [PATCH 21/41] fix: log errors setting agent version as debug (#6374) * feat: ignore NotFound error for setting agentVersion * fix: debug log instead of ignore peer not found for setting agentVersion * fix: remove NotFound check and only debug log error setting agentVersion Co-authored-by: Nico Flaig --------- Co-authored-by: Nico Flaig --- packages/beacon-node/src/network/peers/peerManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/beacon-node/src/network/peers/peerManager.ts b/packages/beacon-node/src/network/peers/peerManager.ts index 94af8f06ea03..2275178e13e3 100644 --- a/packages/beacon-node/src/network/peers/peerManager.ts +++ b/packages/beacon-node/src/network/peers/peerManager.ts @@ -620,7 +620,7 @@ export class PeerManager { }, {retries: 3, retryDelay: 1000} ).catch((err) => { - this.logger.error("Error setting agentVersion for the peer", {peerId: peerData.peerId.toString()}, err); + this.logger.debug("Error setting agentVersion for the peer", {peerId: peerData.peerId.toString()}, err); }); }; From 237439266adc69dbe30ea938cb4aca73160913e5 Mon Sep 17 00:00:00 2001 From: Cayman Date: Thu, 1 Feb 2024 10:52:44 -0500 Subject: [PATCH 22/41] chore: update chainsafe dependencies (#6380) --- packages/beacon-node/package.json | 10 +- packages/cli/package.json | 12 +- packages/flare/package.json | 2 +- packages/light-client/package.json | 4 +- packages/prover/package.json | 2 +- packages/state-transition/package.json | 2 +- packages/test-utils/package.json | 2 +- packages/utils/package.json | 2 +- yarn.lock | 1547 ++++++------------------ 9 files changed, 395 insertions(+), 1188 deletions(-) diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 174ed8cbb125..90f2026e1873 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -95,12 +95,12 @@ }, "dependencies": { "@chainsafe/as-chacha20poly1305": "^0.1.0", - "@chainsafe/as-sha256": "^0.3.1", + "@chainsafe/as-sha256": "^0.4.1", "@chainsafe/bls": "7.1.1", "@chainsafe/blst": "^0.2.9", - "@chainsafe/discv5": "^7.1.0", - "@chainsafe/enr": "^2.0.2", - "@chainsafe/libp2p-gossipsub": "^11.1.0", + "@chainsafe/discv5": "^9.0.0", + "@chainsafe/enr": "^3.0.0", + "@chainsafe/libp2p-gossipsub": "^11.2.0", "@chainsafe/libp2p-noise": "^14.1.0", "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/prometheus-gc-stats": "^1.0.0", @@ -153,7 +153,7 @@ "systeminformation": "^5.17.12", "uint8-varint": "^2.0.2", "uint8arraylist": "^2.4.7", - "uint8arrays": "^4.0.9", + "uint8arrays": "^5.0.1", "xxhash-wasm": "1.0.2" }, "devDependencies": { diff --git a/packages/cli/package.json b/packages/cli/package.json index d21e523696ef..1b172087b180 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -52,13 +52,13 @@ "blockchain" ], "dependencies": { - "@chainsafe/as-sha256": "^0.3.1", + "@chainsafe/as-sha256": "^0.4.1", "@chainsafe/bls": "7.1.1", - "@chainsafe/bls-keygen": "^0.3.0", - "@chainsafe/bls-keystore": "^3.0.0", + "@chainsafe/bls-keygen": "^0.4.0", + "@chainsafe/bls-keystore": "^3.0.1", "@chainsafe/blst": "^0.2.9", - "@chainsafe/discv5": "^7.1.0", - "@chainsafe/enr": "^2.0.2", + "@chainsafe/discv5": "^9.0.0", + "@chainsafe/enr": "^3.0.0", "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/ssz": "^0.14.0", "@chainsafe/threads": "^1.11.1", @@ -90,7 +90,7 @@ "proper-lockfile": "^4.1.2", "rimraf": "^4.4.1", "source-map-support": "^0.5.21", - "uint8arrays": "^4.0.9", + "uint8arrays": "^5.0.1", "uuidv4": "^6.2.13", "yargs": "^17.7.1" }, diff --git a/packages/flare/package.json b/packages/flare/package.json index a353598bcd77..6524562c9c82 100644 --- a/packages/flare/package.json +++ b/packages/flare/package.json @@ -59,7 +59,7 @@ ], "dependencies": { "@chainsafe/bls": "7.1.1", - "@chainsafe/bls-keygen": "^0.3.0", + "@chainsafe/bls-keygen": "^0.4.0", "@lodestar/api": "^1.15.0", "@lodestar/config": "^1.15.0", "@lodestar/params": "^1.15.0", diff --git a/packages/light-client/package.json b/packages/light-client/package.json index 831498e2fff7..ef65e57fdef4 100644 --- a/packages/light-client/package.json +++ b/packages/light-client/package.json @@ -79,10 +79,10 @@ "strict-event-emitter-types": "^2.0.0" }, "devDependencies": { - "@chainsafe/as-sha256": "^0.3.1", + "@chainsafe/as-sha256": "^0.4.1", "@types/qs": "^6.9.7", "qs": "^6.11.1", - "uint8arrays": "^4.0.9" + "uint8arrays": "^5.0.1" }, "keywords": [ "ethereum", diff --git a/packages/prover/package.json b/packages/prover/package.json index b5c7eac31033..efeace5dfb65 100644 --- a/packages/prover/package.json +++ b/packages/prover/package.json @@ -78,7 +78,7 @@ "@lodestar/params": "^1.15.0", "@lodestar/types": "^1.15.0", "@lodestar/utils": "^1.15.0", - "ethereum-cryptography": "^1.2.0", + "ethereum-cryptography": "^2.0.0", "find-up": "^6.3.0", "http-proxy": "^1.18.1", "js-yaml": "^4.1.0", diff --git a/packages/state-transition/package.json b/packages/state-transition/package.json index e3c97c127e08..4524edf43859 100644 --- a/packages/state-transition/package.json +++ b/packages/state-transition/package.json @@ -58,7 +58,7 @@ }, "types": "lib/index.d.ts", "dependencies": { - "@chainsafe/as-sha256": "^0.3.1", + "@chainsafe/as-sha256": "^0.4.1", "@chainsafe/bls": "7.1.1", "@chainsafe/blst": "^0.2.9", "@chainsafe/persistent-merkle-tree": "^0.6.1", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index ab3474370a28..cb742ad4ba56 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -58,7 +58,7 @@ ], "dependencies": { "@chainsafe/bls": "7.1.1", - "@chainsafe/bls-keystore": "^3.0.0", + "@chainsafe/bls-keystore": "^3.0.1", "@lodestar/params": "^1.15.0", "@lodestar/utils": "^1.15.0", "axios": "^1.3.4", diff --git a/packages/utils/package.json b/packages/utils/package.json index 751d6551ee48..7c94e4288b12 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -39,7 +39,7 @@ }, "types": "lib/index.d.ts", "dependencies": { - "@chainsafe/as-sha256": "^0.3.1", + "@chainsafe/as-sha256": "^0.4.1", "any-signal": "3.0.1", "bigint-buffer": "^1.1.5", "case": "^1.6.3", diff --git a/yarn.lock b/yarn.lock index ce67d0db390d..839c0dce5e90 100644 --- a/yarn.lock +++ b/yarn.lock @@ -256,26 +256,11 @@ resolved "https://registry.yarnpkg.com/@chainsafe/as-chacha20poly1305/-/as-chacha20poly1305-0.1.0.tgz#7da6f8796f9b42dac6e830a086d964f1f9189e09" integrity sha512-BpNcL8/lji/GM3+vZ/bgRWqJ1q5kwvTFmGPk7pxm/QQZDbaMI98waOHjEymTjq2JmdD/INdNBFOVSyJofXg7ew== -"@chainsafe/as-sha256@^0.3.1": - version "0.3.1" - resolved "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz" - integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== - "@chainsafe/as-sha256@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.4.1.tgz#cfc0737e25f8c206767bdb6703e7943e5d44513e" integrity sha512-IqeeGwQihK6Y2EYLFofqs2eY2ep1I2MvQXHzOAI+5iQN51OZlUkrLgyAugu2x86xZewDk5xas7lNczkzFzF62w== -"@chainsafe/bls-hd-key@^0.2.0": - version "0.2.1" - resolved "https://registry.npmjs.org/@chainsafe/bls-hd-key/-/bls-hd-key-0.2.1.tgz" - integrity sha512-FGmRLcOd9KxfH9q7x+FT20lJy9ooQ/Xd5fFLFGpPaf9GW4AnE0oGPGakPuV5//g8db7OzZ3ZfVMKtB4M7qq/wA== - dependencies: - assert "^2.0.0" - bcrypto "^5.4.0" - bn.js "^5.1.1" - buffer "^5.4.3" - "@chainsafe/bls-hd-key@^0.3.0": version "0.3.0" resolved "https://registry.npmjs.org/@chainsafe/bls-hd-key/-/bls-hd-key-0.3.0.tgz" @@ -283,16 +268,6 @@ dependencies: "@noble/hashes" "^1.0.0" -"@chainsafe/bls-keygen@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@chainsafe/bls-keygen/-/bls-keygen-0.3.0.tgz#d7472a945f6f49b5cb357241bfba2f5c12a635c5" - integrity sha512-5Iq6E5E987hyio74G1fXPYI3t9iVeHxRX1tDMpnCV9T82rPz061yFsMz3W3aXE26+k6+fcz0bsYX3ijOizkx+A== - dependencies: - "@chainsafe/bls-hd-key" "^0.2.0" - bip39 "^3.0.2" - buffer "^5.4.3" - randombytes "^2.1.0" - "@chainsafe/bls-keygen@^0.4.0": version "0.4.0" resolved "https://registry.npmjs.org/@chainsafe/bls-keygen/-/bls-keygen-0.4.0.tgz" @@ -302,13 +277,13 @@ "@noble/hashes" "^1.0.0" "@scure/bip39" "^1.0.0" -"@chainsafe/bls-keystore@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@chainsafe/bls-keystore/-/bls-keystore-3.0.0.tgz#e28c979f7664417e4917fa0d4d32fa2b9416e9c6" - integrity sha512-vlRIIXnn555wq2emhqnSR7btno17M0sCcfdQ+Dhgr7IH6n0CMoTGw9qcrpnNYwM+9OPm3matSYeZc9mNlXf7fQ== +"@chainsafe/bls-keystore@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@chainsafe/bls-keystore/-/bls-keystore-3.0.1.tgz#1eaf1d89d3628b5fbab62fcd10f48703f2c428cc" + integrity sha512-U6m/tMgdEUq60RhcIj7xUD5n6zuavSbThR+szuAglmUa9gY8QfInxXpGAT4hyc2QjbLy9115vJVyhyu7TDl+DQ== dependencies: - ethereum-cryptography "^1.0.0" - uuid "8.3.2" + ethereum-cryptography "^2.0.0" + uuid "^9.0.0" "@chainsafe/bls@7.1.1": version "7.1.1" @@ -328,37 +303,36 @@ node-fetch "^2.6.1" node-gyp "^8.4.0" -"@chainsafe/discv5@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@chainsafe/discv5/-/discv5-7.1.0.tgz#c892075c84bdc75428774d4993e7346205ff8724" - integrity sha512-spO801KWe0C9XrXkVt4E1paXP1ZtfsgxOf+FSW6yCDQTWFVGRfcl/ww4B7JtdJOnZauqaHqXxAuNBpSafJoalw== +"@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== dependencies: - "@chainsafe/enr" "^2.0.2" - "@libp2p/crypto" "^3.0.4" + "@chainsafe/enr" "^3.0.0" + "@libp2p/crypto" "^4.0.1" "@libp2p/interface" "^1.1.1" "@multiformats/multiaddr" "^12.1.10" bcrypto "^5.4.0" bigint-buffer "^1.1.5" debug "^4.3.1" - err-code "^3.0.1" lru-cache "^10.1.0" rlp "^2.2.6" strict-event-emitter-types "^2.0.0" -"@chainsafe/enr@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@chainsafe/enr/-/enr-2.0.2.tgz#29814ae506a87d466640cddbac49369029334f09" - integrity sha512-90IEkHHb5ZHk2BuyX5QkLomaxH+HXF41wFOzDC2Hpla6c3ersxAJJms4kJSot7j20Uzfka4Xjxvkwjj8WfL77g== +"@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== dependencies: - "@libp2p/crypto" "^3.0.4" + "@libp2p/crypto" "^4.0.1" "@libp2p/interface" "^1.1.1" "@libp2p/peer-id" "^4.0.4" "@multiformats/multiaddr" "^12.1.10" - base64url "^3.0.1" - bcrypto "^5.4.0" bigint-buffer "^1.1.5" + ethereum-cryptography "^2.1.3" rlp "^2.2.6" uint8-varint "^2.0.2" + uint8arrays "^5.0.1" "@chainsafe/eslint-plugin-node@^11.2.3": version "11.2.3" @@ -390,26 +364,26 @@ resolved "https://registry.yarnpkg.com/@chainsafe/is-ip/-/is-ip-2.0.2.tgz#7311e7403f11d8c5cfa48111f56fcecaac37c9f6" integrity sha512-ndGqEMG1W5WkGagaqOZHpPU172AGdxr+LD15sv3WIUvT5oCFUrG1Y0CW/v2Egwj4JXEvSibaIIIqImsm98y1nA== -"@chainsafe/libp2p-gossipsub@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-gossipsub/-/libp2p-gossipsub-11.1.0.tgz#e5ebd8dd08601845073f3b8c9601e047d7bdc279" - integrity sha512-6baEtpC9gu5D9bXv86zIdNIOekKgQPV3KRWvnsldtsKpiWtUv6K2mLsl3wsDi0nW/c3zxTAneaJMTLQoSXysJQ== - dependencies: - "@libp2p/crypto" "^3.0.1" - "@libp2p/interface" "^1.0.1" - "@libp2p/interface-internal" "^1.0.1" - "@libp2p/peer-id" "^4.0.1" - "@libp2p/pubsub" "^9.0.0" - "@multiformats/multiaddr" "^12.1.3" +"@chainsafe/libp2p-gossipsub@^11.2.0": + version "11.2.0" + resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-gossipsub/-/libp2p-gossipsub-11.2.0.tgz#4134dc68d9e3e0c327474b48fbd6e1f76f97550b" + integrity sha512-VymXl4Z4qEIUxH4FjgbcVqyuapVHhzrJxADO4t84QOOWv9f8uQYV+c0cgwjneOW3XyTYBOHaZqyTHTngTrKjtQ== + 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" + "@multiformats/multiaddr" "^12.1.14" abortable-iterator "^5.0.1" denque "^2.1.0" - it-length-prefixed "^9.0.1" + it-length-prefixed "^9.0.4" it-pipe "^3.0.1" - it-pushable "^3.2.0" - multiformats "^12.0.1" - protobufjs "^7.2.4" - uint8arraylist "^2.4.3" - uint8arrays "^4.0.4" + it-pushable "^3.2.3" + multiformats "^13.0.1" + protobufjs "^7.2.6" + uint8arraylist "^2.4.8" + uint8arrays "^5.0.1" "@chainsafe/libp2p-noise@^14.1.0": version "14.1.0" @@ -1456,7 +1430,7 @@ "@multiformats/mafmt" "^12.1.6" "@multiformats/multiaddr" "^12.1.10" -"@libp2p/crypto@^3.0.0", "@libp2p/crypto@^3.0.1", "@libp2p/crypto@^3.0.4": +"@libp2p/crypto@^3.0.0", "@libp2p/crypto@^3.0.4": version "3.0.4" resolved "https://registry.yarnpkg.com/@libp2p/crypto/-/crypto-3.0.4.tgz#8768b262c24a036774c6c5e290a1f0d76535a7d3" integrity sha512-FzSwBo+RJOUzdzEwug5ZL4dAGKwEBWTLzj+EmUTHHY6c87+oLh571DQk/w0oYObSD9hYbcKePgSBaZeBx0JaZg== @@ -1470,6 +1444,20 @@ uint8arraylist "^2.4.3" uint8arrays "^5.0.0" +"@libp2p/crypto@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@libp2p/crypto/-/crypto-4.0.1.tgz#350f3397c8fba18d30a74173c3791fe199821062" + integrity sha512-lKGbX8TvQt4JbqlttdexEz2VtYJnTwY31kVBDQviwt0pMF+6Uy2hzNnEQ1FHZBwnow8BIlyb6UevHfgyOFlnkw== + dependencies: + "@libp2p/interface" "^1.1.2" + "@noble/curves" "^1.1.0" + "@noble/hashes" "^1.3.3" + asn1js "^3.0.5" + multiformats "^13.0.0" + protons-runtime "^5.0.0" + uint8arraylist "^2.4.7" + uint8arrays "^5.0.0" + "@libp2p/identify@^1.0.9": version "1.0.9" resolved "https://registry.yarnpkg.com/@libp2p/identify/-/identify-1.0.9.tgz#6756d74919b7a171c7cdcdce45669b9f633fbb0f" @@ -1487,7 +1475,7 @@ uint8arrays "^5.0.0" wherearewe "^2.0.1" -"@libp2p/interface-internal@^1.0.1", "@libp2p/interface-internal@^1.0.5": +"@libp2p/interface-internal@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@libp2p/interface-internal/-/interface-internal-1.0.5.tgz#b7687e4c5cb765fd686fcd442d2cc4c49e8304d7" integrity sha512-qT4APD2nZKEGnkn4LfM2mzNbYv9bx/2FyvYaJ4exjzIIBPiRmjrek7hfWErKkazCDwO51+WuZ/DERdd32O9Fxg== @@ -1497,7 +1485,17 @@ "@multiformats/multiaddr" "^12.1.10" uint8arraylist "^2.4.3" -"@libp2p/interface@^1.0.0", "@libp2p/interface@^1.0.1", "@libp2p/interface@^1.1.1": +"@libp2p/interface-internal@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/interface-internal/-/interface-internal-1.0.7.tgz#e15ad52e148e31558972dd2f4800ad8be61ced88" + integrity sha512-r1nGpnGdkq0U7ow5i093OPWPBJXQP3BGwijino8cCZokYwF2P/CU+yeYvL8ncL8fPYLKuuUjLNGO4Z8Th5sqSQ== + dependencies: + "@libp2p/interface" "^1.1.2" + "@libp2p/peer-collections" "^5.1.5" + "@multiformats/multiaddr" "^12.1.10" + uint8arraylist "^2.4.7" + +"@libp2p/interface@^1.0.0", "@libp2p/interface@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@libp2p/interface/-/interface-1.1.1.tgz#f37ea4930bd74e1299fbcafa49fdab39a28abba9" integrity sha512-g6xgF+q38ZDTRkjuJfuOByS4N0zGld+VPRiWPXYX8wA/9vS6lqJwKUoC6V33KUhP/zXHCkJaSD6z94fUbNM8vw== @@ -1509,6 +1507,18 @@ progress-events "^1.0.0" uint8arraylist "^2.4.3" +"@libp2p/interface@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@libp2p/interface/-/interface-1.1.2.tgz#debfd9d1bd4b81929c9e30eb35c2801ca246ce2b" + integrity sha512-uC4hxtEJuWiDiZfokkSNEEbCzdyZrqb5kp67Wc5PjZsySZ2IoImdIfie003yQXlB1xBp/XUJzdC6kVu4M7LUmg== + dependencies: + "@multiformats/multiaddr" "^12.1.10" + it-pushable "^3.2.3" + it-stream-types "^2.0.1" + multiformats "^13.0.0" + progress-events "^1.0.0" + uint8arraylist "^2.4.7" + "@libp2p/logger@^4.0.1", "@libp2p/logger@^4.0.4": version "4.0.4" resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-4.0.4.tgz#98c5357e8b857d93a506f6818db6abe734d342ee" @@ -1520,6 +1530,17 @@ interface-datastore "^8.2.0" multiformats "^13.0.0" +"@libp2p/logger@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-4.0.5.tgz#6790776b4b2d587b75ccbdf85885c5d11533d19f" + integrity sha512-cXETMNZINnxeQBlfQ2S4di92FDDU89R7RHagrpebGrM7oLl5nf/Mw6myc23kGaM3/2YG3ko2rl9sYjemu0azTA== + dependencies: + "@libp2p/interface" "^1.1.2" + "@multiformats/multiaddr" "^12.1.10" + debug "^4.3.4" + interface-datastore "^8.2.0" + multiformats "^13.0.0" + "@libp2p/mdns@^10.0.10": version "10.0.10" resolved "https://registry.yarnpkg.com/@libp2p/mdns/-/mdns-10.0.10.tgz#02f08f1a485e3640ce575460af63a0b8c4171b64" @@ -1564,13 +1585,13 @@ uint8arraylist "^2.4.3" uint8arrays "^5.0.0" -"@libp2p/peer-collections@^5.0.0", "@libp2p/peer-collections@^5.1.3": - version "5.1.3" - resolved "https://registry.yarnpkg.com/@libp2p/peer-collections/-/peer-collections-5.1.3.tgz#52734a31fe52f01f2ff67132ed0eae28b3229ae4" - integrity sha512-qiQHO8s4neLaAZmjHHWvPc091Lp9nOEokjnTmrE2/YBNjKoiA1aPCf7gM/KasynuquFceTQBDVd/Y79Mfqxw4w== +"@libp2p/peer-collections@^5.1.3", "@libp2p/peer-collections@^5.1.5": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@libp2p/peer-collections/-/peer-collections-5.1.5.tgz#8b241f129dd94f5b56a17fc0614b8e9b80687b44" + integrity sha512-/9VisdPC7+15n/0XntjGCzJ2Ky/zZnqdnuLNEwdu2LuTCbWTaqItG36ecgcVdO9L/V4mELwgY5XCjZKBDrYgjA== dependencies: - "@libp2p/interface" "^1.1.1" - "@libp2p/peer-id" "^4.0.4" + "@libp2p/interface" "^1.1.2" + "@libp2p/peer-id" "^4.0.5" "@libp2p/peer-id-factory@^4.0.3": version "4.0.3" @@ -1584,12 +1605,12 @@ uint8arraylist "^2.4.3" uint8arrays "^5.0.0" -"@libp2p/peer-id@^4.0.0", "@libp2p/peer-id@^4.0.1", "@libp2p/peer-id@^4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@libp2p/peer-id/-/peer-id-4.0.4.tgz#3de8f012f2abdc1ab287ad652d24de587e653ca3" - integrity sha512-UHWpo0f34IOaAhlvMNtCMAFVVhv29Dy3IqNvfugFNwzv5p+Jo6TfPGd78H7RX2WIzyVzIgBYxVxmIIHHcqZQ5Q== +"@libp2p/peer-id@^4.0.0", "@libp2p/peer-id@^4.0.4", "@libp2p/peer-id@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@libp2p/peer-id/-/peer-id-4.0.5.tgz#ed8be246b4d7ba2b7806968b4bfa8d59b82a4b2a" + integrity sha512-/J9U6I/CWSOsYrTpFZpRQrhOhi+bp9WFp7+9Gc7kVt/oevIYTapUEjpxevjViem9ddR5RbdYeCj4ZLHA04QOoQ== dependencies: - "@libp2p/interface" "^1.1.1" + "@libp2p/interface" "^1.1.2" multiformats "^13.0.0" uint8arrays "^5.0.0" @@ -1637,24 +1658,24 @@ prom-client "^15.0.0" uint8arraylist "^2.4.3" -"@libp2p/pubsub@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@libp2p/pubsub/-/pubsub-9.0.0.tgz#e9d3869addd653868f87797849dbebfd23cd3a38" - integrity sha512-yvgKBNKtF09x4ahbxJrxj/OBTNvOoJibR28YaTlrlCIDU78wMMhIx89Ma14g2FAN1OsxagifyAgq188vGrsGfA== - dependencies: - "@libp2p/crypto" "^3.0.1" - "@libp2p/interface" "^1.0.1" - "@libp2p/interface-internal" "^1.0.1" - "@libp2p/peer-collections" "^5.0.0" - "@libp2p/peer-id" "^4.0.1" - "@libp2p/utils" "^5.0.2" +"@libp2p/pubsub@^9.0.8": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@libp2p/pubsub/-/pubsub-9.0.8.tgz#4c222c94edb5a5b623ed10fa7555bb70a19ddc0d" + integrity sha512-p2UEfjQPMQgEJTXPdinWCMA6A1sLR7Hvfu8mtoOS1azgtTtqmMCNPtx+3acnNSnWItQFswl9w2HWjspfUcCF1w== + dependencies: + "@libp2p/crypto" "^4.0.1" + "@libp2p/interface" "^1.1.2" + "@libp2p/interface-internal" "^1.0.7" + "@libp2p/peer-collections" "^5.1.5" + "@libp2p/peer-id" "^4.0.5" + "@libp2p/utils" "^5.2.3" it-length-prefixed "^9.0.3" it-pipe "^3.0.1" - it-pushable "^3.2.1" - multiformats "^12.1.3" - p-queue "^7.4.1" - uint8arraylist "^2.4.3" - uint8arrays "^4.0.6" + it-pushable "^3.2.3" + multiformats "^13.0.0" + p-queue "^8.0.0" + uint8arraylist "^2.4.7" + uint8arrays "^5.0.0" "@libp2p/tcp@9.0.10": version "9.0.10" @@ -1668,25 +1689,26 @@ "@types/sinon" "^17.0.0" stream-to-it "^0.2.2" -"@libp2p/utils@^5.0.2", "@libp2p/utils@^5.2.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@libp2p/utils/-/utils-5.2.0.tgz#896bcb9ceb5b90caea0b2a8a5bb353dc2116cc13" - integrity sha512-zAremC/0u7mhS32TS++WBlsjwmKKKonEB7dZMfTtKH0QfghII8vcBOgBCTEqhtm0AqwsT6vIlm6wAg9bbZKbQA== +"@libp2p/utils@^5.2.0", "@libp2p/utils@^5.2.3": + version "5.2.3" + resolved "https://registry.yarnpkg.com/@libp2p/utils/-/utils-5.2.3.tgz#32c1dd68d661d7d93ed3428c7817da2e4b85817f" + integrity sha512-N+9pQHQ/XrxXP/RCiWUSUXnkFCWcyzMxlGXY+aQUfcfLi5M2eFtPSz2Tc5dWmYGVJeI9CNafok+72YUsPZHfOQ== dependencies: "@chainsafe/is-ip" "^2.0.2" - "@libp2p/interface" "^1.1.1" - "@libp2p/logger" "^4.0.4" + "@libp2p/interface" "^1.1.2" + "@libp2p/logger" "^4.0.5" "@multiformats/multiaddr" "^12.1.10" "@multiformats/multiaddr-matcher" "^1.1.0" + delay "^6.0.0" get-iterator "^2.0.1" is-loopback-addr "^2.0.1" - it-pushable "^3.2.2" + it-pushable "^3.2.3" it-stream-types "^2.0.1" + netmask "^2.0.2" p-defer "^4.0.0" - private-ip "^3.0.1" race-event "^1.1.0" - race-signal "^1.0.1" - uint8arraylist "^2.4.3" + race-signal "^1.0.2" + uint8arraylist "^2.4.7" "@lukeed/ms@^2.0.1": version "2.0.1" @@ -1709,15 +1731,15 @@ "@multiformats/multiaddr" "^12.0.0" multiformats "^12.0.1" -"@multiformats/multiaddr@^12.0.0", "@multiformats/multiaddr@^12.1.10", "@multiformats/multiaddr@^12.1.3": - version "12.1.12" - resolved "https://registry.yarnpkg.com/@multiformats/multiaddr/-/multiaddr-12.1.12.tgz#d1609933dc5589d53f6b77fb88fe5e5ea787deae" - integrity sha512-hrY4uN/oeYhn410jBSpVXn37eenn4djKOj6Dh20Yh4xzGgqmS6u+/X08zQfHgWNjk7NJejPUcRfHEfs8e/MOcw== +"@multiformats/multiaddr@^12.0.0", "@multiformats/multiaddr@^12.1.10", "@multiformats/multiaddr@^12.1.14", "@multiformats/multiaddr@^12.1.3": + version "12.1.14" + resolved "https://registry.yarnpkg.com/@multiformats/multiaddr/-/multiaddr-12.1.14.tgz#d021072667f4dfc566cdddcb45feee60fecc8cfd" + integrity sha512-1C0Mo73chzu7pTzTquuKs5vUtw70jhqg1i6pUNznGb0WV6RFa6vyB+D697Os5+cLx+DiItrAY6VzMtlGQsMzYg== dependencies: "@chainsafe/is-ip" "^2.0.1" "@chainsafe/netmask" "^2.0.0" "@libp2p/interface" "^1.0.0" - dns-over-http-resolver "3.0.0" + dns-over-http-resolver "^3.0.2" multiformats "^13.0.0" uint8-varint "^2.0.1" uint8arrays "^5.0.0" @@ -1792,46 +1814,29 @@ resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.4.0.tgz#e3f69e3ce935683dd8dadb636652a5cb5cd5958c" integrity sha512-xaUaUUDWbHIFSxaQ/pIe+33VG2mfJp6N/KxKLmZr5biWdNznCAmfu24QRhX10BbVAuqOahAoyp0S4M9md6GPDw== -"@noble/curves@1.0.0", "@noble/curves@~1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" - integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw== - dependencies: - "@noble/hashes" "1.3.0" - -"@noble/curves@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" - integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== +"@noble/curves@1.3.0", "@noble/curves@^1.1.0", "@noble/curves@~1.3.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== dependencies: - "@noble/hashes" "1.3.1" + "@noble/hashes" "1.3.3" "@noble/hashes@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== -"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" - integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== - -"@noble/hashes@1.3.0", "@noble/hashes@^1.2.0", "@noble/hashes@^1.3.0", "@noble/hashes@~1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" - integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== - -"@noble/hashes@1.3.1", "@noble/hashes@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" - integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== +"@noble/hashes@1.3.3", "@noble/hashes@^1.0.0", "@noble/hashes@^1.2.0", "@noble/hashes@^1.3.0", "@noble/hashes@^1.3.1", "@noble/hashes@^1.3.3", "@noble/hashes@~1.3.2": + 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.0.0", "@noble/hashes@~1.0.0": +"@noble/hashes@~1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae" integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg== -"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": +"@noble/secp256k1@1.7.1": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== @@ -2551,47 +2556,30 @@ "@scure/base@~1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@scure/base/-/base-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.0.0.tgz#109fb595021de285f05a7db6806f2f48296fcee7" integrity sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA== -"@scure/base@~1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== - -"@scure/bip32@1.1.5": +"@scure/base@~1.1.4": version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" - integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== - dependencies: - "@noble/hashes" "~1.2.0" - "@noble/secp256k1" "~1.7.0" - "@scure/base" "~1.1.0" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" + integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== -"@scure/bip32@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.0.tgz#6c8d980ef3f290987736acd0ee2e0f0d50068d87" - integrity sha512-bcKpo1oj54hGholplGLpqPHRbIsnbixFtc06nwuNM5/dwSXOq/AAYoIBRsBmnZJSdfeNW5rnff7NTAz3ZCqR9Q== - dependencies: - "@noble/curves" "~1.0.0" - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" - integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== +"@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== dependencies: - "@noble/hashes" "~1.2.0" - "@scure/base" "~1.1.0" + "@noble/curves" "~1.3.0" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.4" -"@scure/bip39@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.0.tgz#a207e2ef96de354de7d0002292ba1503538fc77b" - integrity sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg== +"@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== dependencies: - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.4" "@scure/bip39@^1.0.0": version "1.0.0" @@ -2960,11 +2948,6 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.192.tgz#5790406361a2852d332d41635d927f1600811285" integrity sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A== -"@types/long@^4.0.1": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" - integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== - "@types/minimatch@^3.0.3": version "3.0.5" resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz" @@ -3011,11 +2994,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.5.tgz#4c6a79adf59a8e8193ac87a0e522605b16587258" integrity sha512-2qGq5LAOTh9izcc0+F+dToFigBWiK1phKPt7rNhOqJSr35y8rlIBjDwGtFSgAI6MGIhjwOVNSQZVdJsZJ2uR1w== -"@types/node@11.11.6": - version "11.11.6" - resolved "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz" - integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== - "@types/node@18.15.13": version "18.15.13" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" @@ -3859,11 +3837,6 @@ array-differ@^3.0.0: resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - array-ify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" @@ -3961,6 +3934,15 @@ asn1@^0.2.4: dependencies: safer-buffer "~2.1.0" +asn1js@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.5.tgz#5ea36820443dbefb51cc7f88a2ebb5b462114f38" + integrity sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ== + dependencies: + pvtsutils "^1.3.2" + pvutils "^1.1.3" + tslib "^2.4.0" + assert@^1.1.1: version "1.5.0" resolved "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz" @@ -4023,13 +4005,6 @@ atomic-sleep@^1.0.0: resolved "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== -available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" - available-typed-arrays@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" @@ -4091,11 +4066,6 @@ base64-js@^1.0.2, base64-js@^1.3.1: resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -base64url@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz" - integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== - basic-ftp@^5.0.2: version "5.0.3" resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.3.tgz#b14c0fe8111ce001ec913686434fe0c2fb461228" @@ -4173,16 +4143,6 @@ bintrees@1.0.1: resolved "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz" integrity sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ= -bip39@^3.0.2: - version "3.0.4" - resolved "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz" - integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== - dependencies: - "@types/node" "11.11.6" - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - bip39@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3" @@ -4391,7 +4351,7 @@ buffer@4.9.2, buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.2.1, buffer@^5.4.3, buffer@^5.5.0, buffer@^5.7.1: +buffer@^5.2.1, buffer@^5.5.0, buffer@^5.7.1: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -4573,13 +4533,14 @@ cacheable-request@^7.0.2: normalize-url "^6.0.1" responselike "^2.0.0" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" callsites@^3.0.0, callsites@^3.1.0: version "3.1.0" @@ -5304,14 +5265,7 @@ dateformat@^3.0.3: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1: - version "4.3.1" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@4.3.4, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.0.0, 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: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -5417,10 +5371,10 @@ defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== -define-data-property@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.0.tgz#0db13540704e1d8d479a0656cf781267531b9451" - integrity sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g== +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== dependencies: get-intrinsic "^1.2.1" gopd "^1.0.1" @@ -5436,15 +5390,7 @@ define-lazy-prop@^3.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -define-properties@^1.2.0: +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== @@ -5462,6 +5408,11 @@ degenerator@^5.0.0: escodegen "^2.1.0" esprima "^4.0.1" +delay@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-6.0.0.tgz#43749aefdf6cabd9e17b0d00bd3904525137e607" + integrity sha512-2NJozoOHQ4NuZuVIr5CWd0iiLVIRSDepakaovIN+9eIDHEhdCAEvSy2cuf1DCrPPQLvHmbqTHODlhHg8UCy4zw== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -5564,7 +5515,7 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -dns-over-http-resolver@3.0.0, dns-over-http-resolver@^2.1.1: +dns-over-http-resolver@^2.1.1, dns-over-http-resolver@^3.0.2: version "2.1.3" resolved "https://registry.yarnpkg.com/dns-over-http-resolver/-/dns-over-http-resolver-2.1.3.tgz#bb7f2e10cc18d960339a6e30e21b8c1d99be7b38" integrity sha512-zjRYFhq+CsxPAouQWzOsxNMvEN+SHisjzhX8EMxd2Y0EG3thvn6wXQgMJLnTDImkhe4jhLbOQpXtL10nALBOSA== @@ -5790,147 +5741,26 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.18.0-next.1: - version "1.18.0" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz" - integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.2" - is-callable "^1.2.3" - is-negative-zero "^2.0.1" - is-regex "^1.1.2" - is-string "^1.0.5" - object-inspect "^1.9.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.0" - -es-abstract@^1.18.0-next.2: - version "1.20.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.3.tgz#90b143ff7aedc8b3d189bcfac7f1e3e3f81e9da1" - integrity sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.6" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.2" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" - unbox-primitive "^1.0.2" - -es-abstract@^1.19.0, es-abstract@^1.19.5: - version "1.20.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" - integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - regexp.prototype.flags "^1.4.3" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" - unbox-primitive "^1.0.2" - -es-abstract@^1.20.4: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== - dependencies: - array-buffer-byte-length "^1.0.0" - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.10" - is-weakref "^1.0.2" - object-inspect "^1.12.3" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.7" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" - -es-abstract@^1.22.1: - version "1.22.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.2.tgz#90f7282d91d0ad577f505e423e52d4c1d93c1b8a" - integrity sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA== +es-abstract@^1.18.0-next.2, es-abstract@^1.20.4, 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== dependencies: array-buffer-byte-length "^1.0.0" arraybuffer.prototype.slice "^1.0.2" available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + call-bind "^1.0.5" es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" function.prototype.name "^1.1.6" - get-intrinsic "^1.2.1" + get-intrinsic "^1.2.2" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" - has "^1.0.3" has-property-descriptors "^1.0.0" has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" internal-slot "^1.0.5" is-array-buffer "^3.0.2" is-callable "^1.2.7" @@ -5940,7 +5770,7 @@ es-abstract@^1.22.1: is-string "^1.0.7" is-typed-array "^1.1.12" is-weakref "^1.0.2" - object-inspect "^1.12.3" + object-inspect "^1.13.1" object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.5.1" @@ -5954,7 +5784,7 @@ es-abstract@^1.22.1: typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.11" + which-typed-array "^1.1.13" es-set-tostringtag@^2.0.1: version "2.0.1" @@ -6157,17 +5987,7 @@ eslint-visitor-keys@^1.1.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: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - -eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint-visitor-keys@^3.4.3: +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== @@ -6220,16 +6040,7 @@ esm@^3.2.25: resolved "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz" integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== -espree@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.0.tgz#80869754b1c6560f32e3b6929194a3fe07c5b82f" - integrity sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -espree@^9.6.1: +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== @@ -6279,25 +6090,15 @@ esutils@^2.0.2: resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -ethereum-cryptography@^1.0.0, ethereum-cryptography@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" - integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== - dependencies: - "@noble/hashes" "1.2.0" - "@noble/secp256k1" "1.7.1" - "@scure/bip32" "1.1.5" - "@scure/bip39" "1.1.1" - -ethereum-cryptography@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.0.0.tgz#e052b49fa81affae29402e977b8d3a31f88612b6" - integrity sha512-g25m4EtfQGjstWgVE1aIz7XYYjf3kH5kG17ULWVB5dH6uLahsoltOhACzSxyDV+fhn4gbR4xRrOXGe6r2uh4Bg== +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== dependencies: - "@noble/curves" "1.0.0" - "@noble/hashes" "1.3.0" - "@scure/bip32" "1.3.0" - "@scure/bip39" "1.2.0" + "@noble/curves" "1.3.0" + "@noble/hashes" "1.3.3" + "@scure/bip32" "1.3.3" + "@scure/bip39" "1.2.2" ethers@^5.7.1: version "5.7.2" @@ -6508,32 +6309,10 @@ fast-fifo@^1.1.0, fast-fifo@^1.2.0: 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: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-glob@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" - integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-glob@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== +fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -6619,17 +6398,10 @@ fastify@^4.19.0: semver "^7.5.0" tiny-lru "^11.0.1" -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -fastq@^1.6.1: - version "1.11.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz" - integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== +fastq@^1.6.0, fastq@^1.6.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.0.tgz#ca5e1a90b5e68f97fc8b61330d5819b82f5fab03" + integrity sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w== dependencies: reusify "^1.0.4" @@ -6776,11 +6548,6 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" - integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= - foreground-child@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" @@ -6914,26 +6681,11 @@ fstream@^1.0.12: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function-bind@^1.1.2: +function-bind@^1.1.1, function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - function.prototype.name@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" @@ -6949,26 +6701,11 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== -functions-have-names@^1.2.2, functions-have-names@^1.2.3: +functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -gauge@^4.0.0: - version "4.0.2" - resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.2.tgz" - integrity sha512-aSPRm2CvA9R8QyU5eXMFPd+cYkyxLsXHd2l5/FOH2V/eml//M04G6KZOmTap07O1PvEwNcl2NndyLfK8g3QrKA== - dependencies: - ansi-regex "^5.0.1" - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - gauge@^4.0.3: version "4.0.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" @@ -7021,35 +6758,7 @@ get-func-name@^2.0.0, get-func-name@^2.0.2: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-intrinsic@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" - -get-intrinsic@^1.2.2: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== @@ -7064,12 +6773,7 @@ get-iterator@^1.0.2: resolved "https://registry.npmjs.org/get-iterator/-/get-iterator-1.0.2.tgz" integrity sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg== -get-iterator@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-2.0.0.tgz#c9ac9f8002e5d8d6b4dc9dae07c30945022a58c1" - integrity sha512-BDJawD5PU2gZv6Vlp8O28H4GnZcsr3h9gZUvnAP5xXP3WOy/QAoOsyMepSkw21jur+4t5Vppde72ChjhTIzxzg== - -get-iterator@^2.0.1: +get-iterator@^2.0.0, get-iterator@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-2.0.1.tgz#a904829f61bace789e0d64bd1a504c511a015c3f" integrity sha512-7HuY/hebu4gryTDT7O/XY/fvY9wRByEGdK6QOa4of8npTcv0+NS6frFKABcf6S9EBAsveTuKTsZQQBFMMNILIg== @@ -7249,7 +6953,7 @@ glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.0: +glob@^8.0.0, glob@^8.0.1: version "8.1.0" resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -7260,28 +6964,7 @@ glob@^8.0.0: minimatch "^5.0.1" once "^1.3.0" -glob@^8.0.1: - version "8.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" - integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -glob@^9.2.0: - version "9.3.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.4.tgz#e75dee24891a80c25cc7ee1dd327e126b98679af" - integrity sha512-qaSc49hojMOv1EPM4EuyITjDSgSKI0rthoHnvE81tcOi1SCVndHko7auqxdQ14eiQG2NDBJBE86+2xIrbIvrbA== - dependencies: - fs.realpath "^1.0.0" - minimatch "^8.0.2" - minipass "^4.2.4" - path-scurry "^1.6.1" - -glob@^9.3.0, glob@^9.3.1: +glob@^9.2.0, glob@^9.3.1: version "9.3.5" resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== @@ -7370,21 +7053,11 @@ got@^12.6.1: p-cancelable "^3.0.0" responselike "^3.0.0" -graceful-fs@4.2.11, graceful-fs@^4.2.2: +graceful-fs@4.2.11, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -graceful-fs@^4.2.6: - version "4.2.9" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz" - integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== - grapheme-splitter@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" @@ -7427,19 +7100,19 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: - get-intrinsic "^1.1.1" + get-intrinsic "^1.2.2" has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== -has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== @@ -7706,20 +7379,10 @@ ignore-walk@^6.0.0: dependencies: minimatch "^7.4.2" -ignore@^5.0.4, ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -ignore@^5.1.1: - version "5.1.8" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +ignore@^5.0.4, ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" @@ -7841,28 +7504,18 @@ inquirer@^9.1.5: wrap-ansi "^8.1.0" interface-datastore@^8.0.0, interface-datastore@^8.2.0, interface-datastore@^8.2.7: - version "8.2.7" - resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-8.2.7.tgz#6a1e168fd98a271a92b85223bae58fa30031fb9c" - integrity sha512-ot5B5+VogufRfjhedAXZHm5NuEKyYZkDyVpTjBYIrxYUpS5GIfF2soE/dsd/FiBVqubcxa4IEToMXL5ruMwhjw== + version "8.2.10" + resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-8.2.10.tgz#2d7fc026c8185378c4d3433fe942d9d6838f95cb" + integrity sha512-D8RuxMdjOPB+j6WMDJ+I2aXTDzUT6DIVjgzo1E+ODL7w8WrSFl9FXD2SYmgj6vVzdb7Kb5qmAI9pEnDZJz7ifg== dependencies: interface-store "^5.0.0" - nanoid "^5.0.3" - uint8arrays "^4.0.2" + uint8arrays "^5.0.0" 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== -internal-slot@^1.0.3: - version "1.0.6" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" - integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== - dependencies: - get-intrinsic "^1.2.2" - hasown "^2.0.0" - side-channel "^1.0.4" - internal-slot@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" @@ -7882,7 +7535,7 @@ ip-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-5.0.0.tgz#cd313b2ae9c80c07bd3851e12bf4fa4dc5480632" integrity sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw== -ip@^1.1.5, ip@^1.1.8: +ip@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== @@ -7955,16 +7608,11 @@ is-buffer@^2.0.5: resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.3, is-callable@^1.2.6, is-callable@^1.2.7: +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - is-ci@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" @@ -7972,40 +7620,12 @@ is-ci@3.0.1: dependencies: ci-info "^3.2.0" -is-core-module@^2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== +is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.3.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== dependencies: - has "^1.0.3" - -is-core-module@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== - dependencies: - has "^1.0.3" - -is-core-module@^2.3.0: - version "2.5.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz" - integrity sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg== - dependencies: - has "^1.0.3" - -is-core-module@^2.5.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" - integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== - dependencies: - has "^1.0.3" - -is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" - integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== - dependencies: - has "^1.0.3" + hasown "^2.0.0" is-date-object@^1.0.1: version "1.0.5" @@ -8044,14 +7664,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: - version "4.0.1" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-glob@^4.0.1, is-glob@^4.0.3: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, 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== @@ -8109,7 +7722,7 @@ is-nan@^1.2.1: call-bind "^1.0.0" define-properties "^1.1.3" -is-negative-zero@^2.0.1, is-negative-zero@^2.0.2: +is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== @@ -8178,7 +7791,7 @@ is-property@^1.0.0, is-property@^1.0.2: resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== -is-regex@^1.1.2, is-regex@^1.1.4: +is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -8236,35 +7849,13 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" -is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -is-typed-array@^1.1.12: +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: which-typed-array "^1.1.11" -is-typed-array@^1.1.3: - version "1.1.5" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz" - integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== - dependencies: - available-typed-arrays "^1.0.2" - call-bind "^1.0.2" - es-abstract "^1.18.0-next.2" - foreach "^2.0.5" - has-symbols "^1.0.1" - is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" @@ -8324,26 +7915,12 @@ isomorphic-ws@^5.0.0: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== -istanbul-lib-coverage@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz" - integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== - -istanbul-lib-coverage@^3.2.2: +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-report@^3.0.1: +istanbul-lib-report@^3.0.0, istanbul-lib-report@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== @@ -8369,12 +7946,7 @@ istanbul-reports@^3.1.6: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -it-all@^3.0.0, it-all@^3.0.1, it-all@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/it-all/-/it-all-3.0.2.tgz#620b82c702c9c6d1c4caddb6407dba4a4baa970b" - integrity sha512-ujqWETXhsDbF6C+6X6fvRw5ohlowRoy/o/h9BC8D+R3JQ13oLQ153w9gSWkWupOY7omZFQbJiAL1aJo5Gwe2yw== - -it-all@^3.0.4: +it-all@^3.0.0, it-all@^3.0.1, it-all@^3.0.2, it-all@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/it-all/-/it-all-3.0.4.tgz#08f2e3eb3df04fa4525a343dcacfbdf91ffee162" integrity sha512-UMiy0i9DqCHBdWvMbzdYvVGa5/w4t1cc4nchpbnjdLhklglv8mQeEYnii0gvKESJuL1zV32Cqdb33R6/GPfxpQ== @@ -8388,15 +7960,10 @@ it-byte-stream@^1.0.0: it-stream-types "^2.0.1" uint8arraylist "^2.4.1" -it-drain@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/it-drain/-/it-drain-3.0.2.tgz#4fb2ab30119072268c68a895fa5b9f2037942c44" - integrity sha512-0hJvS/4Ktt9wT/bktmovjjMAY8r6FCsXqpL3zjqBBNwoL21VgQfguEnwbLSGuCip9Zq1vfU43cbHkmaRZdBfOg== - -it-drain@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/it-drain/-/it-drain-3.0.3.tgz#f80719d3d0d7e7d02dc298d86ca9d0e7f7bd666b" - integrity sha512-l4s+izxUpFAR2axprpFiCaq0EtxK1QMd0LWbEtau5b+OegiZ5xdRtz35iJyh6KZY9QtuwEiQxydiOfYJc7stoA== +it-drain@^3.0.1, it-drain@^3.0.3: + version "3.0.5" + resolved "https://registry.yarnpkg.com/it-drain/-/it-drain-3.0.5.tgz#d7aed18a16a12c157fa477653fb42c1b4f08491c" + integrity sha512-qYFe4SWdvs9oJGUY5bSjvmiLUMLzFEODNOQUdYdCIkuIgQF+AUB2INhM4yQ09buJ2rhHKDFxvTD/+yUq6qg0XA== it-filter@^3.0.0: version "3.0.2" @@ -8412,39 +7979,27 @@ it-foreach@^2.0.3: dependencies: it-peekable "^3.0.0" -it-length-prefixed-stream@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/it-length-prefixed-stream/-/it-length-prefixed-stream-1.0.2.tgz#dbcb291118fc9cf031c89ab4be3f99cdb452f548" - integrity sha512-gWevodoctgwWUaRJN9t+xEs1H1GQNYAjLCR7FO50fon9Ph4OJGgrxPKTc26QXKrC/cIQZLkHYClphUw0wl1k2A== +it-length-prefixed-stream@^1.0.0, it-length-prefixed-stream@^1.1.1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/it-length-prefixed-stream/-/it-length-prefixed-stream-1.1.6.tgz#b757b96d352da6e97b66002dd2ead32893ba2337" + integrity sha512-MEby4r8n3XIYXjaWT3DweCuhBPQmFVT8RdI1BNjYQ5gelbFD3NLdjYpTI3TVmSEs/aJfgpfVFZzy6iP7OCxIgw== dependencies: it-byte-stream "^1.0.0" - it-length-prefixed "^9.0.1" it-stream-types "^2.0.1" uint8-varint "^2.0.1" uint8arraylist "^2.4.1" -it-length-prefixed-stream@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/it-length-prefixed-stream/-/it-length-prefixed-stream-1.1.4.tgz#5e5a73685e820366d9a9dd944decef55b46f09ef" - integrity sha512-6YcQ5jsaYnuXBqF+oSGjSdSY9jF7HWl7yh+dxYytXxbE2GcdiOpn6pLM7m6AlIID9MCzQqMY5nOzaiatQ8A3/A== - dependencies: - it-byte-stream "^1.0.0" - it-length-prefixed "^9.0.1" - it-stream-types "^2.0.1" - uint8-varint "^2.0.1" - uint8arraylist "^2.4.1" - -it-length-prefixed@^9.0.1, it-length-prefixed@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/it-length-prefixed/-/it-length-prefixed-9.0.3.tgz#73af16f786cab60a0a9bfc2997e88eb26d3a72ca" - integrity sha512-YAu424ceYpXctxtjcLOqn7vJq082CaoP8J646ZusYISfQc3bpzQErgTUqMFj81V262KG2W9/YMBHsy6A/4yvmg== +it-length-prefixed@^9.0.1, it-length-prefixed@^9.0.3, it-length-prefixed@^9.0.4: + version "9.0.4" + resolved "https://registry.yarnpkg.com/it-length-prefixed/-/it-length-prefixed-9.0.4.tgz#8096c3270420fe8abaa920c7b4d5e5895144008e" + integrity sha512-lz28fykbG0jq7s5XtvlzGxO5BeSOw6ikymkRllxjL21V5VKLcvB4pHr9wPvEnsAJ2et1xpOk3BRTMq9XrhgKsg== dependencies: err-code "^3.0.1" it-reader "^6.0.1" it-stream-types "^2.0.1" uint8-varint "^2.0.1" uint8arraylist "^2.0.0" - uint8arrays "^4.0.2" + uint8arrays "^5.0.1" it-map@^3.0.1: version "3.0.3" @@ -8453,14 +8008,7 @@ it-map@^3.0.1: dependencies: it-peekable "^3.0.0" -it-merge@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/it-merge/-/it-merge-3.0.1.tgz#20cc293593586e5afcbfed8ba88a94def5ccfcfa" - integrity sha512-I6hjU1ABO+k3xY1H6JtCSDXvUME88pxIXSgKeT4WI5rPYbQzpr98ldacVuG95WbjaJxKl6Qot6lUdxduLBQPHA== - dependencies: - it-pushable "^3.1.0" - -it-merge@^3.0.1: +it-merge@^3.0.0, it-merge@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/it-merge/-/it-merge-3.0.3.tgz#c7d407c8e0473accf7f9958ce2e0f60276002e84" integrity sha512-FYVU15KC5pb/GQX1Ims+lee8d4pdqGVCpWr0lkNj8o4xuNo7jY71k6GuEiWdP+T7W1bJqewSxX5yoTy5yZpRVA== @@ -8506,19 +8054,7 @@ it-protobuf-stream@^1.0.2: protons-runtime "^5.0.0" uint8arraylist "^2.4.1" -it-pushable@^3.0.0, it-pushable@^3.1.0, it-pushable@^3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/it-pushable/-/it-pushable-3.1.3.tgz#b6f4a1e0236502f12b5661b40468b629799baf0e" - integrity sha512-f50iQ85HISS6DaWCyrqf9QJ6G/kQtKIMf9xZkgZgyOvxEQDfn8OfYcLXXquCqgoLboxQtAW1ZFZyFIAsLHDtJw== - -it-pushable@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/it-pushable/-/it-pushable-3.2.1.tgz#72d7ccf7e7c0ccecf8cbaf74064f7be56e775c59" - integrity sha512-sLFz2Q0oyDCJpTciZog7ipP4vSftfPy3e6JnH6YyztRa1XqkpGQaafK3Jw/JlfEBtCXfnX9uVfcpu3xpSAqCVQ== - dependencies: - p-defer "^4.0.0" - -it-pushable@^3.2.1, it-pushable@^3.2.2: +it-pushable@^3.0.0, it-pushable@^3.1.2, it-pushable@^3.2.0, it-pushable@^3.2.1, it-pushable@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/it-pushable/-/it-pushable-3.2.3.tgz#e2b80aed90cfbcd54b620c0a0785e546d4e5f334" integrity sha512-gzYnXYK8Y5t5b/BnJUr7glfQLO4U5vyb05gPx/TyTw+4Bv1zM9gFk4YsOrnulWefMewlphCjKkakFvj1y99Tcg== @@ -9182,10 +8718,10 @@ lowercase-keys@^3.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== -lru-cache@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" - integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== +lru-cache@^10.1.0, "lru-cache@^9.1.1 || ^10.0.0": + version "10.2.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" + integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== lru-cache@^5.1.1: version "5.1.1" @@ -9201,26 +8737,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.14.1: +lru-cache@^7.14.1, lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: version "7.18.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== -lru-cache@^7.4.4, lru-cache@^7.5.1: - version "7.14.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.14.0.tgz#21be64954a4680e303a09e9468f880b98a0b3c7f" - integrity sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ== - -lru-cache@^7.7.1: - version "7.10.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.10.1.tgz#db577f42a94c168f676b638d15da8fb073448cab" - integrity sha512-BQuhQxPuRl79J5zSXRP+uNzPOyZw2oFI9JLRQ80XswSvg21KMKNtQza9eF42rfI/3Z40RvzBdXgziEkudzjo8A== - -"lru-cache@^9.1.1 || ^10.0.0": - version "10.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" - integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== - magic-string@^0.30.3, magic-string@^0.30.5: version "0.30.5" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" @@ -9252,13 +8773,6 @@ make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - make-error@^1.1.1: version "1.3.6" resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" @@ -9286,28 +8800,7 @@ make-fetch-happen@^10.0.3: socks-proxy-agent "^7.0.0" ssri "^9.0.0" -make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1: - version "11.1.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.0.tgz#f26b05e89317e960b75fd5e080e40d40f8d7b2a5" - integrity sha512-7ChuOzCb1LzdQZrTy0ky6RsCoMYeM+Fh4cY0+4zsJVhNcH5Q3OJojLY1mGkD0xAhWB29lskECVb6ZopofwjldA== - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^4.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" - -make-fetch-happen@^11.0.3, make-fetch-happen@^11.1.1: +make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== @@ -9808,12 +9301,7 @@ multiformats@^12.0.1: resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-12.0.1.tgz#dd3e19dd44114c2672e4795a36888d263be30131" integrity sha512-s01wijBJoDUqESWSzePY0lvTw7J3PVO9x2Cc6ASI5AMZM2Gnhh7BC17+nlFhHKU7dDzaCaRfb+NiqNzOsgPUoQ== -multiformats@^12.1.3: - version "12.1.3" - resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-12.1.3.tgz#cbf7a9861e11e74f8228b21376088cb43ba8754e" - integrity sha512-eajQ/ZH7qXZQR2AgtfpmSMizQzmyYVmCql7pdhldPuYQi4atACekbJaQplk6dWyIi10jCaFnd6pqvcEFXjbaJw== - -multiformats@^13.0.0: +multiformats@^13.0.0, multiformats@^13.0.1: version "13.0.1" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.0.1.tgz#c0622affa5171189eacd57c06f977195ca7acb08" integrity sha512-bt3R5iXe2O8xpp3wkmQhC73b/lC4S2ihU8Dndwcsysqbydqb8N+bpP116qMcClZ17g58iSIwtXUTcg2zT4sniA== @@ -9864,11 +9352,6 @@ nanoid@^4.0.0: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e" integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw== -nanoid@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.3.tgz#6c97f53d793a7a1de6a38ebb46f50f95bf9793c7" - integrity sha512-I7X2b22cxA4LIHXPSqbBCEQSL+1wv8TuoefejsX4HFWyC6jc5JG7CEaxOltiKjc1M+YCS2YkrZZcj4+dytw9GA== - napi-macros@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz" @@ -9919,15 +9402,17 @@ node-domexception@^1.0.0: resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== -node-fetch@2.6.7, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7: +node-fetch@2.6.7: version "2.6.7" - resolved "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz" - integrity sha512-iTASGs+HTFK5E4ZqcMsHmeJ4zodyq8L38lZV33jwqcBJYoUt3HjN4+ot+O9/0b+ke8ddE7UgOtVuZN/OkV19/g== + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" -node-fetch@^2.6.12: - version "2.6.12" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" - integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== +node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -9966,32 +9451,16 @@ node-gyp@^8.4.0: tar "^6.1.2" which "^2.0.2" -node-gyp@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.0.0.tgz#e1da2067427f3eb5bb56820cb62bc6b1e4bd2089" - integrity sha512-Ma6p4s+XCTPxCuAMrOA/IJRmVy16R8Sdhtwl4PrCr7IBlj4cPawF0vg/l7nOT1jPbuNS7lIRJpBSvVsXwEZuzw== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^10.0.3" - nopt "^5.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - -node-gyp@^9.4.0: - version "9.4.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.0.tgz#2a7a91c7cba4eccfd95e949369f27c9ba704f369" - integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== +node-gyp@^9.0.0, node-gyp@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== dependencies: env-paths "^2.2.0" exponential-backoff "^3.1.1" glob "^7.1.4" graceful-fs "^4.2.6" - make-fetch-happen "^11.0.3" + make-fetch-happen "^10.0.3" nopt "^6.0.0" npmlog "^6.0.0" rimraf "^3.0.2" @@ -10202,20 +9671,7 @@ npm-pick-manifest@^8.0.0: npm-package-arg "^10.0.0" semver "^7.3.5" -npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3: - version "14.0.4" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.4.tgz#43dfa55ce7c0d0c545d625c7a916bab5b95f7038" - integrity sha512-pMS2DRkwg+M44ct65zrN/Cr9IHK1+n6weuefAo6Er4lc+/8YBCU0Czq04H3ZiSigluh7pb2rMM5JpgcytctB+Q== - dependencies: - make-fetch-happen "^11.0.0" - minipass "^4.0.0" - minipass-fetch "^3.0.0" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^10.0.0" - proc-log "^3.0.0" - -npm-registry-fetch@^14.0.5: +npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0.5: version "14.0.5" resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== @@ -10230,7 +9686,7 @@ npm-registry-fetch@^14.0.5: npm-run-all@^4.1.5: version "4.1.5" - resolved "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== dependencies: ansi-styles "^3.2.1" @@ -10257,17 +9713,7 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" -npmlog@^6.0.0: - version "6.0.1" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz" - integrity sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.0" - set-blocking "^2.0.0" - -npmlog@^6.0.2: +npmlog@^6.0.0, npmlog@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== @@ -10345,20 +9791,10 @@ object-hash@^2.0.1: resolved "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz" integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== -object-inspect@^1.12.0: - version "1.12.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.1.tgz#28a661153bad7e470e4b01479ef1cb91ce511191" - integrity sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA== - -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-inspect@^1.12.3: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== object-is@^1.0.1: version "1.1.5" @@ -10373,7 +9809,7 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.2, object.assign@^4.1.4: +object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== @@ -10651,13 +10087,13 @@ p-queue@^7.2.0: eventemitter3 "^4.0.7" p-timeout "^5.0.2" -p-queue@^7.4.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-7.4.1.tgz#7f86f853048beca8272abdbb7cec1ed2afc0f265" - integrity sha512-vRpMXmIkYF2/1hLBKisKeVYJZ8S2tZ0zEAmIJgdVKP2nq0nh4qCdf8bgw+ZgKrkh71AOCaqzwbJJk1WtdcF3VA== +p-queue@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-8.0.1.tgz#718b7f83836922ef213ddec263ff4223ce70bef8" + integrity sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA== dependencies: eventemitter3 "^5.0.1" - p-timeout "^5.0.2" + p-timeout "^6.1.2" p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: version "2.1.0" @@ -10676,10 +10112,10 @@ p-timeout@^5.0.2: resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-5.1.0.tgz#b3c691cf4415138ce2d9cfe071dba11f0fee085b" integrity sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew== -p-timeout@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-6.1.1.tgz#bcee5e37d730f5474d973b6ff226751a1a5e6ff1" - integrity sha512-yqz2Wi4fiFRpMmK0L2pGAU49naSUaP23fFIQL2Y6YT+qDGPoFwpvgQM/wzc6F8JoenUkIlAFa4Ql7NguXBxI7w== +p-timeout@^6.0.0, p-timeout@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-6.1.2.tgz#22b8d8a78abf5e103030211c5fc6dee1166a6aa5" + integrity sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ== p-try@^1.0.0: version "1.0.0" @@ -10857,7 +10293,7 @@ path-key@^4.0.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== -path-parse@^1.0.5, path-parse@^1.0.6, path-parse@^1.0.7: +path-parse@^1.0.5, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -10892,7 +10328,7 @@ pathval@^1.1.1: resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -pbkdf2@^3.0.3, pbkdf2@^3.0.9: +pbkdf2@^3.0.3: version "3.1.2" resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== @@ -10913,12 +10349,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4: - version "2.2.3" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz" - integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== - -picomatch@^2.2.1, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -11076,15 +10507,7 @@ progress@2.0.3, progress@^2.0.3: resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prom-client@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-15.0.0.tgz#067da874a2aa5d2e21bd5cdba9f24a8178bdab6a" - integrity sha512-UocpgIrKyA2TKLVZDSfm8rGkL13C19YrQBAiG3xo3aDFWcHedxRxI3z+cIcucoxpSO0h5lff5iv/SXoxyeopeA== - dependencies: - "@opentelemetry/api" "^1.4.0" - tdigest "^0.1.1" - -prom-client@^15.1.0: +prom-client@^15.0.0, prom-client@^15.1.0: version "15.1.0" resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-15.1.0.tgz#816a4a2128da169d0471093baeccc6d2f17a4613" integrity sha512-cCD7jLTqyPdjEPBo/Xk4Iu8jxjuZgZJ3e/oET3L+ZwOuap/7Cw3dH/TJSsZKs1TQLZ2IHpIlRAKw82ef06kmMw== @@ -11128,29 +10551,10 @@ properties-reader@^2.2.0: dependencies: mkdirp "^1.0.4" -protobufjs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.0.0.tgz#8c678e1351fd926178fce5a4213913e8d990974f" - integrity sha512-ffNIEm+quOcYtQvHdW406v1NQmZSuqVklxsXk076BtuFnlYZfigLU+JOMrTD8TUOyqHYbRI/fSVNvgd25YeN3w== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" ">=13.7.0" - long "^5.0.0" - -protobufjs@^7.2.4: - version "7.2.4" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.4.tgz#3fc1ec0cdc89dd91aef9ba6037ba07408485c3ae" - integrity sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ== +protobufjs@^7.0.0, protobufjs@^7.2.6: + version "7.2.6" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.6.tgz#4a0ccd79eb292717aacf07530a07e0ed20278215" + integrity sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -11219,16 +10623,11 @@ proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -psl@^1.1.28: +psl@^1.1.28, psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== -psl@^1.1.33: - version "1.8.0" - resolved "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz" @@ -11251,20 +10650,15 @@ pump@^3.0.0: punycode@1.3.2: version "1.3.2" - resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== -punycode@^2.3.1: +punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== @@ -11281,6 +10675,18 @@ puppeteer-core@^20.9.0: devtools-protocol "0.0.1147663" ws "8.13.0" +pvtsutils@^1.3.2: + version "1.3.5" + resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.5.tgz#b8705b437b7b134cd7fd858f025a23456f1ce910" + integrity sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA== + dependencies: + tslib "^2.6.1" + +pvutils@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3" + integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== + qs@^6.11.0, qs@^6.11.1: version "6.11.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f" @@ -11338,7 +10744,7 @@ race-event@^1.1.0: resolved "https://registry.yarnpkg.com/race-event/-/race-event-1.1.0.tgz#69c2d855653acf11d8b23ea8f6fa50e1180a088b" integrity sha512-8BTiN6IAbov8mqkVEc3LiYbtUzanLfzFhwPF7kZV74ztYeQXdFPIgMCd/sy8xie6ZMtf2JPeMBedx78/RRNO3g== -race-signal@^1.0.1, race-signal@^1.0.2: +race-signal@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/race-signal/-/race-signal-1.0.2.tgz#e42379fba0cec4ee8dab7c9bbbd4aa6e0d14c25f" integrity sha512-o3xNv0iTcIDQCXFlF6fPAMEBRjFxssgGoRqLbg06m+AdzEXXLUmoNOoUHTVz2NoBI8hHwKFKoC6IqyNtWr2bww== @@ -11381,7 +10787,7 @@ read-package-json-fast@^3.0.0: json-parse-even-better-errors "^3.0.0" npm-normalize-package-bin "^3.0.0" -read-package-json@6.0.4: +read-package-json@6.0.4, read-package-json@^6.0.0: version "6.0.4" resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== @@ -11391,16 +10797,6 @@ read-package-json@6.0.4: normalize-package-data "^5.0.0" npm-normalize-package-bin "^3.0.0" -read-package-json@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.1.tgz#566cb06bc05dbddefba4607e9096d5a9efbcd836" - integrity sha512-AaHqXxfAVa+fNL07x8iAghfKOds/XXsu7zoouIVsbm7PEbQ3nMWXlvjcbrNLjElnUHWQtAo4QEa0RXuvD4XlpA== - dependencies: - glob "^9.3.0" - json-parse-even-better-errors "^3.0.0" - normalize-package-data "^5.0.0" - npm-normalize-package-bin "^3.0.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -11444,7 +10840,7 @@ read@^2.0.0: dependencies: mute-stream "~1.0.0" -readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.6: +readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -11476,14 +10872,7 @@ readable-stream@^4.0.0: events "^3.3.0" process "^0.11.10" -readdir-glob@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.2.tgz#b185789b8e6a43491635b6953295c5c5e3fd224c" - integrity sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA== - dependencies: - minimatch "^5.1.0" - -readdir-glob@^1.1.2: +readdir-glob@^1.0.0, readdir-glob@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.3.tgz#c3d831f51f5e7bfa62fa2ffbe4b508c640f09584" integrity sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA== @@ -11522,15 +10911,6 @@ regenerator-runtime@^0.11.0: resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - regexp.prototype.flags@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" @@ -11587,23 +10967,7 @@ resolve-pkg-maps@^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.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.10.1: - version "1.16.1" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.16.1.tgz" - integrity sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig== - dependencies: - path-parse "^1.0.6" - -resolve@^1.17.0: +resolve@^1.10.0, resolve@^1.10.1, 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== @@ -11796,24 +11160,10 @@ rustbn.js@~0.2.0: resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== -rxjs@^7.2.0: - version "7.3.0" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.3.0.tgz" - integrity sha512-p2yuGIg9S1epc3vrjKf6iVb3RCaAYjYskkO+jHIaV0IjOPlJop4UnodOoFb2xeNwlguqLYvGw1b1McillYb5Gw== - dependencies: - tslib "~2.1.0" - -rxjs@^7.5.5: - version "7.5.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" - integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== - dependencies: - tslib "^2.1.0" - -rxjs@^7.8.0: - version "7.8.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== +rxjs@^7.2.0, rxjs@^7.5.5, rxjs@^7.8.0: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" @@ -11912,7 +11262,7 @@ semver@7.5.3: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.1: +semver@^6.1.0, semver@^6.2.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -11955,6 +11305,17 @@ set-cookie-parser@^2.4.1: resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz" integrity sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg== +set-function-length@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.0.tgz#2f81dc6c16c7059bda5ab7c82c11f03a515ed8e1" + integrity sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w== + dependencies: + define-data-property "^1.1.1" + function-bind "^1.1.2" + get-intrinsic "^1.2.2" + gopd "^1.0.1" + has-property-descriptors "^1.0.1" + set-function-name@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" @@ -12130,15 +11491,7 @@ socks-proxy-agent@^8.0.1, socks-proxy-agent@^8.0.2: debug "^4.3.4" socks "^2.7.1" -socks@^2.6.1, socks@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz" - integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA== - dependencies: - ip "^1.1.5" - smart-buffer "^4.2.0" - -socks@^2.7.1: +socks@^2.6.1, socks@^2.6.2, socks@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== @@ -12396,15 +11749,6 @@ string.prototype.padend@^3.0.0: define-properties "^1.1.3" es-abstract "^1.18.0-next.2" -string.prototype.trim@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" - integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - string.prototype.trim@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" @@ -12414,24 +11758,6 @@ string.prototype.trim@^1.2.8: define-properties "^1.2.0" es-abstract "^1.22.1" -string.prototype.trimend@^1.0.4, string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - string.prototype.trimend@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" @@ -12441,24 +11767,6 @@ string.prototype.trimend@^1.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" -string.prototype.trimstart@^1.0.4, string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - string.prototype.trimstart@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" @@ -12496,14 +11804,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - -strip-ansi@^7.1.0: +strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== @@ -12892,16 +12193,7 @@ tough-cookie@^3.0.1: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.1.2" - -tough-cookie@^4.1.3: +tough-cookie@^4.0.0, tough-cookie@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== @@ -12933,7 +12225,7 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== -triple-beam@^1.2.0, triple-beam@^1.3.0: +triple-beam@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== @@ -12991,7 +12283,7 @@ tsconfig@^7.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslib@2.4.0, tslib@^2.3.0, tslib@^2.4.0: +tslib@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== @@ -13001,31 +12293,11 @@ 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.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== - -tslib@^2.0.1: +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.5.0, tslib@^2.6.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== -tslib@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== - -tslib@^2.5.0, tslib@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" - integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== - -tslib@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz" @@ -13197,20 +12469,13 @@ uint8-varint@^2.0.0, uint8-varint@^2.0.1, uint8-varint@^2.0.2: uint8arraylist "^2.0.0" uint8arrays "^5.0.0" -uint8arraylist@^2.0.0, uint8arraylist@^2.4.1, uint8arraylist@^2.4.3, uint8arraylist@^2.4.7: +uint8arraylist@^2.0.0, uint8arraylist@^2.4.1, uint8arraylist@^2.4.3, uint8arraylist@^2.4.7, uint8arraylist@^2.4.8: version "2.4.8" resolved "https://registry.yarnpkg.com/uint8arraylist/-/uint8arraylist-2.4.8.tgz#5a4d17f4defd77799cb38e93fd5db0f0dceddc12" integrity sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ== dependencies: uint8arrays "^5.0.1" -uint8arrays@^4.0.2, uint8arrays@^4.0.4, uint8arrays@^4.0.6, uint8arrays@^4.0.9: - version "4.0.10" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-4.0.10.tgz#3ec5cde3348903c140e87532fc53f46b8f2e921f" - integrity sha512-AnJNUGGDJAgFw/eWu/Xb9zrVKEGlwJJCaeInlf3BkecE/zcTobk5YXYIPNQJO1q5Hh1QZrQQHf0JvcHqz2hqoA== - dependencies: - multiformats "^12.0.1" - uint8arrays@^5.0.0, uint8arrays@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-5.0.1.tgz#6016ef944379eabb6de605934ead4d7a698c9f07" @@ -13218,7 +12483,7 @@ uint8arrays@^5.0.0, uint8arrays@^5.0.1: dependencies: multiformats "^13.0.0" -unbox-primitive@^1.0.0, unbox-primitive@^1.0.2: +unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== @@ -13281,7 +12546,7 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== -universalify@^0.1.0, universalify@^0.1.2: +universalify@^0.1.0: version "0.1.2" resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== @@ -13384,19 +12649,7 @@ util@^0.11.0: dependencies: inherits "2.0.3" -util@^0.12.0: - version "0.12.3" - resolved "https://registry.npmjs.org/util/-/util-0.12.3.tgz" - integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - safe-buffer "^5.1.2" - which-typed-array "^1.1.2" - -util@^0.12.4, util@^0.12.5: +util@^0.12.0, util@^0.12.4, util@^0.12.5: version "0.12.5" resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -13894,41 +13147,16 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-typed-array@^1.1.11: - version "1.1.11" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" - integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which-typed-array@^1.1.2: - version "1.1.4" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz" - integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== - dependencies: - available-typed-arrays "^1.0.2" - call-bind "^1.0.0" - es-abstract "^1.18.0-next.1" - foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" - -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== dependencies: available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + call-bind "^1.0.4" for-each "^0.3.3" gopd "^1.0.1" has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" which@^1.2.9: version "1.3.1" @@ -13983,18 +13211,10 @@ winston-daily-rotate-file@^4.7.1: triple-beam "^1.3.0" winston-transport "^4.4.0" -winston-transport@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz" - integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== - dependencies: - readable-stream "^2.3.7" - triple-beam "^1.2.0" - -winston-transport@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa" - integrity sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q== +winston-transport@^4.4.0, winston-transport@^4.5.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.6.0.tgz#f1c1a665ad1b366df72199e27892721832a19e1b" + integrity sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg== dependencies: logform "^2.3.2" readable-stream "^3.6.0" @@ -14105,7 +13325,7 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -ws@8.13.0, ws@^8.8.1: +ws@8.13.0: version "8.13.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== @@ -14115,10 +13335,10 @@ ws@8.5.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== -ws@^8.14.2, ws@^8.8.0: - version "8.14.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" - integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== +ws@^8.14.2, ws@^8.8.0, ws@^8.8.1: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== xml-name-validator@^5.0.0: version "5.0.0" @@ -14127,7 +13347,7 @@ xml-name-validator@^5.0.0: xml2js@0.4.19: version "0.4.19" - resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== dependencies: sax ">=0.6.0" @@ -14135,7 +13355,7 @@ xml2js@0.4.19: xml2js@^0.4.19: version "0.4.23" - resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== dependencies: sax ">=0.6.0" @@ -14224,7 +13444,7 @@ yargs@16.2.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@17.7.1, yargs@^17.5.1, yargs@^17.6.2, yargs@^17.7.1: +yargs@17.7.1: version "17.7.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== @@ -14237,7 +13457,7 @@ yargs@17.7.1, yargs@^17.5.1, yargs@^17.6.2, yargs@^17.7.1: y18n "^5.0.5" yargs-parser "^21.1.1" -yargs@17.7.2: +yargs@17.7.2, yargs@^17.1.1, yargs@^17.5.1, yargs@^17.6.2, yargs@^17.7.1: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== @@ -14250,19 +13470,6 @@ yargs@17.7.2: y18n "^5.0.5" yargs-parser "^21.1.1" -yargs@^17.1.1: - version "17.6.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" - integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" From b2c83ce79306e902f56614ec76d952bc338d82fe Mon Sep 17 00:00:00 2001 From: Phil Ngo <58080811+philknows@users.noreply.github.com> Date: Thu, 1 Feb 2024 10:53:33 -0500 Subject: [PATCH 23/41] chore: update holesky.ts to include Lodestar bootnode (#6383) Update holesky.ts to include Lodestar bootnode --- packages/cli/src/networks/holesky.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/networks/holesky.ts b/packages/cli/src/networks/holesky.ts index 5c0f99ee53de..0f89cadaed33 100644 --- a/packages/cli/src/networks/holesky.ts +++ b/packages/cli/src/networks/holesky.ts @@ -13,4 +13,5 @@ export const bootEnrs = [ "enr:-Ly4QGbOw4xNel5EhmDsJJ-QhC9XycWtsetnWoZ0uRy381GHdHsNHJiCwDTOkb3S1Ade0SFQkWJX_pgb3g8Jfh93rvMBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBpt9l0BAFwAAABAAAAAAAAgmlkgnY0gmlwhJK-DYCJc2VjcDI1NmsxoQOxKv9sv3zKF8GDewgFGGHKP5HCZZpPpTrwl9eXKAWGxIhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA", "enr:-LS4QG0uV4qvcpJ-HFDJRGBmnlD3TJo7yc4jwK8iP7iKaTlfQ5kZvIDspLMJhk7j9KapuL9yyHaZmwTEZqr10k9XumyCEcmHYXR0bmV0c4gAAAAABgAAAIRldGgykGm32XQEAXAAAAEAAAAAAACCaWSCdjSCaXCErK4j-YlzZWNwMjU2azGhAgfWRBEJlb7gAhXIB5ePmjj2b8io0UpEenq1Kl9cxStJg3RjcIIjKIN1ZHCCIyg", "enr:-Le4QLoE1wFHSlGcm48a9ZESb_MRLqPPu6G0vHqu4MaUcQNDHS69tsy-zkN0K6pglyzX8m24mkb-LtBcbjAYdP1uxm4BhGV0aDKQabfZdAQBcAAAAQAAAAAAAIJpZIJ2NIJpcIQ5gR6Wg2lwNpAgAUHQBwEQAAAAAAAAADR-iXNlY3AyNTZrMaEDPMSNdcL92uNIyCsS177Z6KTXlbZakQqxv3aQcWawNXeDdWRwgiMohHVkcDaCI4I", + "enr:-KG4QC9Wm32mtzB5Fbj2ri2TEKglHmIWgvwTQCvNHBopuwpNAi1X6qOsBg_Z1-Bee-kfSrhzUQZSgDUyfH5outUprtoBgmlkgnY0gmlwhHEel3eDaXA2kP6AAAAAAAAAAlBW__4Srr-Jc2VjcDI1NmsxoQO7KE63Z4eSI55S1Yn7q9_xFkJ1Wt-a3LgiXuKGs19s0YN1ZHCCIyiEdWRwNoIjKA", ]; From 863ee5f6252771ba3dc5024a1c385d0920402918 Mon Sep 17 00:00:00 2001 From: tuyennhv Date: Fri, 2 Feb 2024 02:51:07 +0700 Subject: [PATCH 24/41] fix: getAttestationsForBlock performance issue (#6367) * chore: enhance perf tests for getAttestationsForBlock * refactor: group attestations, cache forkchoice validation * fix: return only not seen indices for notSeenValidatorFn * fix: lint * chore: bring back finalizedSync.test.ts --- .../opPools/aggregatedAttestationPool.ts | 307 ++++++++++++------ .../test/e2e/sync/finalizedSync.test.ts | 124 +++++++ .../opPools/aggregatedAttestationPool.test.ts | 236 +++++++++++--- .../opPools/aggregatedAttestationPool.test.ts | 85 ++++- 4 files changed, 591 insertions(+), 161 deletions(-) create mode 100644 packages/beacon-node/test/e2e/sync/finalizedSync.test.ts diff --git a/packages/beacon-node/src/chain/opPools/aggregatedAttestationPool.ts b/packages/beacon-node/src/chain/opPools/aggregatedAttestationPool.ts index 00309d322a11..db7922758732 100644 --- a/packages/beacon-node/src/chain/opPools/aggregatedAttestationPool.ts +++ b/packages/beacon-node/src/chain/opPools/aggregatedAttestationPool.ts @@ -1,12 +1,6 @@ import bls from "@chainsafe/bls"; import {toHexString} from "@chainsafe/ssz"; -import { - ForkName, - MAX_ATTESTATIONS, - MIN_ATTESTATION_INCLUSION_DELAY, - SLOTS_PER_EPOCH, - TIMELY_SOURCE_FLAG_INDEX, -} from "@lodestar/params"; +import {ForkName, MAX_ATTESTATIONS, MIN_ATTESTATION_INCLUSION_DELAY, SLOTS_PER_EPOCH} from "@lodestar/params"; import {phase0, Epoch, Slot, ssz, ValidatorIndex, RootHex} from "@lodestar/types"; import { CachedBeaconStateAllForks, @@ -24,9 +18,17 @@ import {InsertOutcome} from "./types.js"; type DataRootHex = string; +type CommitteeIndex = number; + type AttestationWithScore = {attestation: phase0.Attestation; score: number}; -type GetParticipationFn = (epoch: Epoch, committee: number[]) => Set | null; +/** + * This function returns not seen participation for a given epoch and committee. + * Return null if all validators are seen or no info to check. + */ +type GetNotSeenValidatorsFn = (epoch: Epoch, committee: number[]) => Set | null; + +type ValidateAttestationDataFn = (attData: phase0.AttestationData) => boolean; /** * Limit the max attestations with the same AttestationData. @@ -37,13 +39,13 @@ type GetParticipationFn = (epoch: Epoch, committee: number[]) => Set | n const MAX_RETAINED_ATTESTATIONS_PER_GROUP = 4; /** - * On mainnet, each slot has 64 committees, and each block has 128 attestations max so we don't - * want to store more than 2 per group. + * On mainnet, each slot has 64 committees, and each block has 128 attestations max so in average + * we get 2 attestation per groups. + * Starting from Jan 2024, we have a performance issue getting attestations for a block. Based on the + * fact that lot of groups will have only 1 attestation since it's full of participation increase this number + * a bit higher than average. This also help decrease number of slots to search for attestations. */ -const MAX_ATTESTATIONS_PER_GROUP = 2; - -/** Same to https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.5/specs/altair/beacon-chain.md#has_flag */ -const TIMELY_SOURCE = 1 << TIMELY_SOURCE_FLAG_INDEX; +const MAX_ATTESTATIONS_PER_GROUP = 3; /** * Maintain a pool of aggregated attestations. Attestations can be retrieved for inclusion in a block @@ -52,19 +54,22 @@ const TIMELY_SOURCE = 1 << TIMELY_SOURCE_FLAG_INDEX; * Note that we want to remove attestations with attesters that were included in the chain. */ export class AggregatedAttestationPool { - private readonly attestationGroupByDataHashBySlot = new MapDef>( - () => new Map() - ); + private readonly attestationGroupByDataHashByIndexBySlot = new MapDef< + Slot, + Map> + >(() => new Map>()); private lowestPermissibleSlot = 0; /** For metrics to track size of the pool */ getAttestationCount(): {attestationCount: number; attestationDataCount: number} { let attestationCount = 0; let attestationDataCount = 0; - for (const attestationGroupByData of this.attestationGroupByDataHashBySlot.values()) { - attestationDataCount += attestationGroupByData.size; - for (const attestationGroup of attestationGroupByData.values()) { - attestationCount += attestationGroup.getAttestationCount(); + for (const attestationGroupByDataByIndex of this.attestationGroupByDataHashByIndexBySlot.values()) { + for (const attestationGroupByData of attestationGroupByDataByIndex.values()) { + attestationDataCount += attestationGroupByData.size; + for (const attestationGroup of attestationGroupByData.values()) { + attestationCount += attestationGroup.getAttestationCount(); + } } } return {attestationCount, attestationDataCount}; @@ -84,7 +89,12 @@ export class AggregatedAttestationPool { return InsertOutcome.Old; } - const attestationGroupByDataHash = this.attestationGroupByDataHashBySlot.getOrDefault(slot); + const attestationGroupByDataHashByIndex = this.attestationGroupByDataHashByIndexBySlot.getOrDefault(slot); + let attestationGroupByDataHash = attestationGroupByDataHashByIndex.get(attestation.data.index); + if (!attestationGroupByDataHash) { + attestationGroupByDataHash = new Map(); + attestationGroupByDataHashByIndex.set(attestation.data.index, attestationGroupByDataHash); + } let attestationGroup = attestationGroupByDataHash.get(dataRootHex); if (!attestationGroup) { attestationGroup = new MatchingDataAttestationGroup(committee, attestation.data); @@ -100,7 +110,7 @@ export class AggregatedAttestationPool { /** Remove attestations which are too old to be included in a block. */ prune(clockSlot: Slot): void { // Only retain SLOTS_PER_EPOCH slots - pruneBySlot(this.attestationGroupByDataHashBySlot, clockSlot, SLOTS_PER_EPOCH); + pruneBySlot(this.attestationGroupByDataHashByIndexBySlot, clockSlot, SLOTS_PER_EPOCH); this.lowestPermissibleSlot = Math.max(clockSlot - SLOTS_PER_EPOCH, 0); } @@ -112,15 +122,19 @@ export class AggregatedAttestationPool { const stateEpoch = state.epochCtx.epoch; const statePrevEpoch = stateEpoch - 1; - const getParticipation = getParticipationFn(state); + const notSeenValidatorsFn = getNotSeenValidatorsFn(state); + const validateAttestationDataFn = getValidateAttestationDataFn(forkChoice, state); const attestationsByScore: AttestationWithScore[] = []; - const slots = Array.from(this.attestationGroupByDataHashBySlot.keys()).sort((a, b) => b - a); + const slots = Array.from(this.attestationGroupByDataHashByIndexBySlot.keys()).sort((a, b) => b - a); + let minScore = Number.MAX_SAFE_INTEGER; + let slotCount = 0; slot: for (const slot of slots) { - const attestationGroupByDataHash = this.attestationGroupByDataHashBySlot.get(slot); + slotCount++; + const attestationGroupByDataHashByIndex = this.attestationGroupByDataHashByIndexBySlot.get(slot); // should not happen - if (!attestationGroupByDataHash) { + if (!attestationGroupByDataHashByIndex) { throw Error(`No aggregated attestation pool for slot=${slot}`); } @@ -134,34 +148,64 @@ export class AggregatedAttestationPool { continue; // Invalid attestations } - const attestationGroups = Array.from(attestationGroupByDataHash.values()); - for (const attestationGroup of attestationGroups) { - if (!isValidAttestationData(forkChoice, state, attestationGroup.data)) { + const slotDelta = stateSlot - slot; + const shuffling = state.epochCtx.getShufflingAtEpoch(epoch); + const slotCommittees = shuffling.committees[slot % SLOTS_PER_EPOCH]; + for (const [committeeIndex, attestationGroupByData] of attestationGroupByDataHashByIndex.entries()) { + // all attestations will be validated against the state in next step so we can get committee from the state + // this is an improvement to save the notSeenValidatorsFn call for the same slot/index instead of the same attestation data + if (committeeIndex > slotCommittees.length) { + // invalid index, should not happen continue; } - const participation = getParticipation(epoch, attestationGroup.committee); - if (participation === null) { + + const committee = slotCommittees[committeeIndex]; + const notSeenAttestingIndices = notSeenValidatorsFn(epoch, committee); + if (notSeenAttestingIndices === null || notSeenAttestingIndices.size === 0) { + continue; + } + + if ( + slotCount > 2 && + attestationsByScore.length >= MAX_ATTESTATIONS && + notSeenAttestingIndices.size / slotDelta < minScore + ) { + // after 2 slots, there are a good chance that we have 2 * MAX_ATTESTATIONS attestations and break the for loop early + // if not, we may have to scan all slots in the pool + // if we have enough attestations and the max possible score is lower than scores of `attestationsByScore`, we should skip + // otherwise it takes time to check attestation, add it and remove it later after the sort by score continue; } - // TODO: Is it necessary to validateAttestation for: - // - Attestation committee index not within current committee count - // - Attestation aggregation bits length does not match committee length - // - // These properties should not change after being validate in gossip - // IF they have to be validated, do it only with one attestation per group since same data - // The committeeCountPerSlot can be precomputed once per slot - - attestationsByScore.push( - ...attestationGroup.getAttestationsForBlock(participation).map((attestation) => ({ - attestation: attestation.attestation, - score: attestation.notSeenAttesterCount / (stateSlot - slot), - })) - ); - - // Stop accumulating attestations there are enough that may have good scoring - if (attestationsByScore.length > MAX_ATTESTATIONS * 2) { - break slot; + for (const attestationGroup of attestationGroupByData.values()) { + if (!validateAttestationDataFn(attestationGroup.data)) { + continue; + } + + // TODO: Is it necessary to validateAttestation for: + // - Attestation committee index not within current committee count + // - Attestation aggregation bits length does not match committee length + // + // These properties should not change after being validate in gossip + // IF they have to be validated, do it only with one attestation per group since same data + // The committeeCountPerSlot can be precomputed once per slot + for (const {attestation, notSeenAttesterCount} of attestationGroup.getAttestationsForBlock( + notSeenAttestingIndices + )) { + const score = notSeenAttesterCount / slotDelta; + if (score < minScore) { + minScore = score; + } + attestationsByScore.push({ + attestation, + score, + }); + } + + // Stop accumulating attestations there are enough that may have good scoring + if (attestationsByScore.length >= MAX_ATTESTATIONS * 2) { + break slot; + } } } } @@ -183,13 +227,15 @@ export class AggregatedAttestationPool { * @param bySlot slot to filter, `bySlot === attestation.data.slot` */ getAll(bySlot?: Slot): phase0.Attestation[] { - let attestationGroupsArr: Map[]; + let attestationGroupsArr: Map[]; if (bySlot === undefined) { - attestationGroupsArr = Array.from(this.attestationGroupByDataHashBySlot.values()); + attestationGroupsArr = Array.from(this.attestationGroupByDataHashByIndexBySlot.values()).flatMap((byIndex) => + Array.from(byIndex.values()) + ); } else { - const attestationGroups = this.attestationGroupByDataHashBySlot.get(bySlot); - if (!attestationGroups) throw Error(`No attestations for slot ${bySlot}`); - attestationGroupsArr = [attestationGroups]; + const attestationGroupsByIndex = this.attestationGroupByDataHashByIndexBySlot.get(bySlot); + if (!attestationGroupsByIndex) throw Error(`No attestations for slot ${bySlot}`); + attestationGroupsArr = Array.from(attestationGroupsByIndex.values()); } const attestations: phase0.Attestation[] = []; @@ -224,6 +270,7 @@ export class MatchingDataAttestationGroup { private readonly attestations: AttestationWithIndex[] = []; constructor( + // TODO: no need committee here readonly committee: ValidatorIndex[], readonly data: phase0.AttestationData ) {} @@ -284,24 +331,18 @@ export class MatchingDataAttestationGroup { return InsertOutcome.NewData; } - getAttestationsForBlock(seenAttestingIndices: Set): AttestationNonParticipant[] { + /** + * Get AttestationNonParticipant for this groups of same attestation data. + * @param notSeenAttestingIndices not seen attestting indices, i.e. indices in the same committee + * @returns an array of AttestationNonParticipant + */ + getAttestationsForBlock(notSeenAttestingIndices: Set): AttestationNonParticipant[] { const attestations: AttestationNonParticipant[] = []; - - const committeeLen = this.committee.length; - const committeeSeenAttesting = new Array(committeeLen); - - // Intersect committee with participation only once for all attestations - for (let i = 0; i < committeeLen; i++) { - committeeSeenAttesting[i] = seenAttestingIndices.has(this.committee[i]); - } - for (const {attestation} of this.attestations) { - const {aggregationBits} = attestation; let notSeenAttesterCount = 0; - - for (let i = 0; i < committeeLen; i++) { - // TODO: Optimize aggregationBits.get() in bulk for the entire BitArray - if (!committeeSeenAttesting[i] && aggregationBits.get(i)) { + const {aggregationBits} = attestation; + for (const notSeenIndex of notSeenAttestingIndices) { + if (aggregationBits.get(notSeenIndex)) { notSeenAttesterCount++; } } @@ -311,9 +352,13 @@ export class MatchingDataAttestationGroup { } } - return attestations - .sort((a, b) => b.notSeenAttesterCount - a.notSeenAttesterCount) - .slice(0, MAX_ATTESTATIONS_PER_GROUP); + if (attestations.length <= MAX_ATTESTATIONS_PER_GROUP) { + return attestations; + } else { + return attestations + .sort((a, b) => b.notSeenAttesterCount - a.notSeenAttesterCount) + .slice(0, MAX_ATTESTATIONS_PER_GROUP); + } } /** Get attestations for API. */ @@ -335,7 +380,7 @@ export function aggregateInto(attestation1: AttestationWithIndex, attestation2: * Pre-compute participation from a CachedBeaconStateAllForks, for use to check if an attestation's committee * has already attested or not. */ -export function getParticipationFn(state: CachedBeaconStateAllForks): GetParticipationFn { +export function getNotSeenValidatorsFn(state: CachedBeaconStateAllForks): GetNotSeenValidatorsFn { if (state.config.getForkName(state.slot) === ForkName.phase0) { // Get attestations to be included in a phase0 block. // As we are close to altair, this is not really important, it's mainly for e2e. @@ -344,18 +389,29 @@ export function getParticipationFn(state: CachedBeaconStateAllForks): GetPartici const phase0State = state as CachedBeaconStatePhase0; const stateEpoch = computeEpochAtSlot(state.slot); - const previousEpochParticipants = extractParticipation( + const previousEpochParticipants = extractParticipationPhase0( phase0State.previousEpochAttestations.getAllReadonly(), state ); - const currentEpochParticipants = extractParticipation(phase0State.currentEpochAttestations.getAllReadonly(), state); - - return (epoch: Epoch) => { - return epoch === stateEpoch - ? currentEpochParticipants - : epoch === stateEpoch - 1 - ? previousEpochParticipants - : null; + const currentEpochParticipants = extractParticipationPhase0( + phase0State.currentEpochAttestations.getAllReadonly(), + state + ); + + return (epoch: Epoch, committee: number[]) => { + const participants = + epoch === stateEpoch ? currentEpochParticipants : epoch === stateEpoch - 1 ? previousEpochParticipants : null; + if (participants === null) { + return null; + } + + const notSeenAttestingIndices = new Set(); + for (const [i, validatorIndex] of committee.entries()) { + if (!participants.has(validatorIndex)) { + notSeenAttestingIndices.add(i); + } + } + return notSeenAttestingIndices.size === 0 ? null : notSeenAttestingIndices; }; } @@ -374,20 +430,24 @@ export function getParticipationFn(state: CachedBeaconStateAllForks): GetPartici const participationStatus = epoch === stateEpoch ? currentParticipation : epoch === stateEpoch - 1 ? previousParticipation : null; - if (participationStatus === null) return null; + if (participationStatus === null) { + return null; + } - const seenValidatorIndices = new Set(); - for (const validatorIndex of committee) { - if (flagIsTimelySource(participationStatus[validatorIndex])) { - seenValidatorIndices.add(validatorIndex); + const 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); } } - return seenValidatorIndices; + // 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 extractParticipation( +export function extractParticipationPhase0( attestations: phase0.PendingAttestation[], state: CachedBeaconStateAllForks ): Set { @@ -408,7 +468,56 @@ export function extractParticipation( } /** - * Do those validations: + * This returns a function to validate if an attestation data is compatible to a state, + * it's an optimized version of isValidAttestationData(). + * Atttestation data is validated by: + * - Validate the source checkpoint + * - Validate shuffling using beacon block root and target epoch + * + * Here we always validate the source checkpoint, and cache beacon block root + target epoch + * to avoid running the same shuffling validation multiple times. + */ +export function getValidateAttestationDataFn( + forkChoice: IForkChoice, + state: CachedBeaconStateAllForks +): ValidateAttestationDataFn { + const cachedValidatedAttestationData = new Map(); + const {previousJustifiedCheckpoint, currentJustifiedCheckpoint} = state; + const stateEpoch = state.epochCtx.epoch; + return (attData: phase0.AttestationData) => { + const targetEpoch = attData.target.epoch; + let justifiedCheckpoint; + // simple check first + if (targetEpoch === stateEpoch) { + justifiedCheckpoint = currentJustifiedCheckpoint; + } else if (targetEpoch === stateEpoch - 1) { + justifiedCheckpoint = previousJustifiedCheckpoint; + } else { + return false; + } + + if (!ssz.phase0.Checkpoint.equals(attData.source, justifiedCheckpoint)) return false; + + // Shuffling can't have changed if we're in the first few epochs + // Also we can't look back 2 epochs if target epoch is 1 or less + if (stateEpoch < 2 || targetEpoch < 2) { + return true; + } + + // the isValidAttestationData does not depend on slot and index + const beaconBlockRootHex = toHex(attData.beaconBlockRoot); + const cacheKey = beaconBlockRootHex + targetEpoch; + let isValid = cachedValidatedAttestationData.get(cacheKey); + if (isValid === undefined) { + isValid = isValidShuffling(forkChoice, state, beaconBlockRootHex, targetEpoch); + cachedValidatedAttestationData.set(cacheKey, isValid); + } + return isValid; + }; +} + +/** + * A straight forward version to validate attestation data. We don't use it, but keep it here for reference. * - Validate the source checkpoint * - Since we validated attestation's signature in gossip validation function, * we only need to validate the shuffling of attestation @@ -441,6 +550,16 @@ export function isValidAttestationData( if (stateEpoch < 2 || targetEpoch < 2) { return true; } + const beaconBlockRootHex = toHex(data.beaconBlockRoot); + return isValidShuffling(forkChoice, state, beaconBlockRootHex, targetEpoch); +} + +function isValidShuffling( + forkChoice: IForkChoice, + state: CachedBeaconStateAllForks, + blockRootHex: RootHex, + targetEpoch: Epoch +): boolean { // Otherwise the shuffling is determined by the block at the end of the target epoch // minus the shuffling lookahead (usually 2). We call this the "pivot". const pivotSlot = computeStartSlotAtEpoch(targetEpoch - 1) - 1; @@ -450,7 +569,7 @@ export function isValidAttestationData( // pivot block is the same as the current state's pivot block. If it is, then the // attestation's shuffling is the same as the current state's. // To account for skipped slots, find the first block at *or before* the pivot slot. - const beaconBlockRootHex = toHex(data.beaconBlockRoot); + const beaconBlockRootHex = blockRootHex; const beaconBlock = forkChoice.getBlockHex(beaconBlockRootHex); if (!beaconBlock) { throw Error(`Attestation data.beaconBlockRoot ${beaconBlockRootHex} not found in forkchoice`); @@ -467,7 +586,3 @@ export function isValidAttestationData( } return attestationDependentRoot === stateDependentRoot; } - -function flagIsTimelySource(flag: number): boolean { - return (flag & TIMELY_SOURCE) === TIMELY_SOURCE; -} diff --git a/packages/beacon-node/test/e2e/sync/finalizedSync.test.ts b/packages/beacon-node/test/e2e/sync/finalizedSync.test.ts new file mode 100644 index 000000000000..d3d06f1fc070 --- /dev/null +++ b/packages/beacon-node/test/e2e/sync/finalizedSync.test.ts @@ -0,0 +1,124 @@ +import {describe, it, afterEach} from "vitest"; +import {assert} from "chai"; +import {fromHexString} from "@chainsafe/ssz"; +import {ChainConfig} from "@lodestar/config"; +import {phase0} from "@lodestar/types"; +import {TimestampFormatCode} from "@lodestar/logger"; +import {SLOTS_PER_EPOCH} from "@lodestar/params"; +import {routes} from "@lodestar/api"; +import {EventData, EventType} from "@lodestar/api/lib/beacon/routes/events.js"; +import {getDevBeaconNode} from "../../utils/node/beacon.js"; +import {waitForEvent} from "../../utils/events/resolver.js"; +import {getAndInitDevValidators} from "../../utils/node/validator.js"; +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 () { + const validatorCount = 8; + const testParams: Pick = { + // eslint-disable-next-line @typescript-eslint/naming-convention + SECONDS_PER_SLOT: 2, + }; + + const afterEachCallbacks: (() => Promise | void)[] = []; + afterEach(async () => { + while (afterEachCallbacks.length > 0) { + const callback = afterEachCallbacks.pop(); + if (callback) await callback(); + } + }); + + it("should do a finalized sync from another BN", async function () { + // single node at beginning, use main thread to verify bls + const genesisSlotsDelay = 4; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const genesisTime = Math.floor(Date.now() / 1000) + genesisSlotsDelay * testParams.SECONDS_PER_SLOT; + + const testLoggerOpts: TestLoggerOpts = { + level: LogLevel.info, + timestampFormat: { + format: TimestampFormatCode.EpochSlot, + genesisTime, + slotsPerEpoch: SLOTS_PER_EPOCH, + secondsPerSlot: testParams.SECONDS_PER_SLOT, + }, + }; + + const loggerNodeA = testLogger("FinalizedSync-Node-A", testLoggerOpts); + const loggerNodeB = testLogger("FinalizedSync-Node-B", testLoggerOpts); + + const bn = await getDevBeaconNode({ + params: testParams, + options: { + sync: {isSingleNode: true}, + network: {allowPublishToZeroPeers: true, useWorker: false}, + chain: {blsVerifyAllMainThread: true}, + }, + validatorCount, + genesisTime, + logger: loggerNodeA, + }); + + afterEachCallbacks.push(() => bn.close()); + + const {validators} = await getAndInitDevValidators({ + node: bn, + logPrefix: "FinalizedSyncVc", + validatorsPerClient: validatorCount, + validatorClientCount: 1, + startIndex: 0, + useRestApi: false, + testLoggerOpts, + }); + + afterEachCallbacks.push(() => Promise.all(validators.map((validator) => validator.close()))); + + // stop beacon node after validators + afterEachCallbacks.push(() => bn.close()); + + await waitForEvent(bn.chain.emitter, ChainEvent.forkChoiceFinalized, 240000); + loggerNodeA.info("Node A emitted finalized checkpoint event"); + + const bn2 = await getDevBeaconNode({ + params: testParams, + options: { + api: {rest: {enabled: false}}, + network: {useWorker: false}, + chain: {blsVerifyAllMainThread: true}, + }, + validatorCount, + genesisTime, + logger: loggerNodeB, + }); + loggerNodeA.info("Node B created"); + + afterEachCallbacks.push(() => bn2.close()); + afterEachCallbacks.push(() => bn2.close()); + + const headSummary = bn.chain.forkChoice.getHead(); + const head = await bn.db.block.get(fromHexString(headSummary.blockRoot)); + if (!head) throw Error("First beacon node has no head block"); + const waitForSynced = waitForEvent( + bn2.chain.emitter, + routes.events.EventType.head, + 100000, + ({block}) => block === headSummary.blockRoot + ); + + await Promise.all([connect(bn2.network, bn.network), onPeerConnect(bn2.network), onPeerConnect(bn.network)]); + loggerNodeA.info("Node A connected to Node B"); + + try { + await waitForSynced; + loggerNodeB.info("Node B synced to Node A, received head block", {slot: head.message.slot}); + } catch (e) { + assert.fail("Failed to sync to other node in time"); + } + }); + }, + // chain is finalized at slot 32, plus 4 slots for genesis delay => ~72s it should sync pretty fast + {timeout: 90000} +); 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 5dd73bafa3f0..4ed8215ac85b 100644 --- a/packages/beacon-node/test/perf/chain/opPools/aggregatedAttestationPool.test.ts +++ b/packages/beacon-node/test/perf/chain/opPools/aggregatedAttestationPool.test.ts @@ -1,13 +1,13 @@ import {itBench} from "@dapplion/benchmark"; -import {expect} from "chai"; import {BitArray, toHexString} from "@chainsafe/ssz"; import { CachedBeaconStateAltair, computeEpochAtSlot, computeStartSlotAtEpoch, getBlockRootAtSlot, + newFilledArray, } from "@lodestar/state-transition"; -import {HISTORICAL_ROOTS_LIMIT, SLOTS_PER_EPOCH, TIMELY_SOURCE_FLAG_INDEX} from "@lodestar/params"; +import {HISTORICAL_ROOTS_LIMIT, SLOTS_PER_EPOCH} from "@lodestar/params"; import {ExecutionStatus, ForkChoice, IForkChoiceStore, ProtoArray} from "@lodestar/fork-choice"; import {ssz} from "@lodestar/types"; // eslint-disable-next-line import/no-relative-packages @@ -15,33 +15,24 @@ import {generatePerfTestCachedStateAltair} from "../../../../../state-transition import {AggregatedAttestationPool} from "../../../../src/chain/opPools/aggregatedAttestationPool.js"; import {computeAnchorCheckpoint} from "../../../../src/chain/initState.js"; -/** Same to https://github.com/ethereum/eth2.0-specs/blob/v1.1.0-alpha.5/specs/altair/beacon-chain.md#has_flag */ -const TIMELY_SOURCE = 1 << TIMELY_SOURCE_FLAG_INDEX; -function flagIsTimelySource(flag: number): boolean { - return (flag & TIMELY_SOURCE) === TIMELY_SOURCE; -} +const vc = 1_500_000; -// Aug 11 2021 -// getAttestationsForBlock -// ✓ getAttestationsForBlock 4.410948 ops/s 226.7086 ms/op - 64 runs 51.8 s -describe("getAttestationsForBlock", () => { +/** + * Jan 2024 + * getAttestationsForBlock vc=1500000 + * ✔ notSeenSlots=1 numMissedVotes=1 numBadVotes=10 10.48105 ops/s 95.41024 ms/op - 12 runs 18.2 s + * ✔ notSeenSlots=1 numMissedVotes=0 numBadVotes=4 11.44517 ops/s 87.37307 ms/op - 13 runs 14.5 s + * ✔ notSeenSlots=2 numMissedVotes=1 numBadVotes=10 23.86144 ops/s 41.90862 ms/op - 18 runs 34.1 s + */ +describe(`getAttestationsForBlock vc=${vc}`, () => { let originalState: CachedBeaconStateAltair; let protoArray: ProtoArray; let forkchoice: ForkChoice; before(function () { - this.timeout(2 * 60 * 1000); // Generating the states for the first time is very slow - - originalState = generatePerfTestCachedStateAltair({goBackOneSlot: true}); - - const previousEpochParticipationArr = originalState.previousEpochParticipation.getAll(); - const currentEpochParticipationArr = originalState.currentEpochParticipation.getAll(); - - const numPreviousEpochParticipation = previousEpochParticipationArr.filter(flagIsTimelySource).length; - const numCurrentEpochParticipation = currentEpochParticipationArr.filter(flagIsTimelySource).length; + this.timeout(5 * 60 * 1000); // Generating the states for the first time is very slow - expect(numPreviousEpochParticipation).to.equal(250000, "Wrong numPreviousEpochParticipation"); - expect(numCurrentEpochParticipation).to.equal(250000, "Wrong numCurrentEpochParticipation"); + originalState = generatePerfTestCachedStateAltair({goBackOneSlot: true, vc}); const {blockHeader, checkpoint} = computeAnchorCheckpoint(originalState.config, originalState); // TODO figure out why getBlockRootAtSlot(originalState, justifiedSlot) is not the same to justifiedCheckpoint.root @@ -125,17 +116,115 @@ describe("getAttestationsForBlock", () => { forkchoice = new ForkChoice(originalState.config, fcStore, protoArray); }); + // notSeenSlots should be >=1 + for (const [notSeenSlots, numMissedVotes, numBadVotes] of [ + [1, 1, 10], + [1, 0, 4], + // notSeenSlots=2 means the previous block slot is missed + [2, 1, 10], + ]) { + itBench({ + id: `notSeenSlots=${notSeenSlots} numMissedVotes=${numMissedVotes} numBadVotes=${numBadVotes}`, + before: () => { + const state = originalState.clone(); + // by default make all validators have full participation + const previousParticipation = newFilledArray(vc, 0b111); + // origState is at slot 0 of epoch so there is no currentParticipation + const currentParticipation = newFilledArray(vc, 0); + const currentEpoch = computeEpochAtSlot(state.slot); + + for (let epochSlot = 0; epochSlot < SLOTS_PER_EPOCH; epochSlot++) { + const slot = state.slot - 1 - epochSlot; + const slotEpoch = computeEpochAtSlot(slot); + const committeeCount = state.epochCtx.getCommitteeCountPerSlot(slotEpoch); + for (let committeeIndex = 0; committeeIndex < committeeCount; committeeIndex++) { + const duties = state.epochCtx.getBeaconCommittee(slot, committeeIndex); + const participationArr = slotEpoch === currentEpoch ? currentParticipation : previousParticipation; + for (const [i, validatorIndex] of duties.entries()) { + // no attestation in previous slot is included yet as that's the spec + // for slot < previous slot, there is missed votes at every committee so the code need to keep looking for attestations because votes are not seen + if (slot >= state.slot - notSeenSlots || i < numMissedVotes) { + participationArr[validatorIndex] = 0; + } + } + } + } + state.previousEpochParticipation = ssz.altair.EpochParticipation.toViewDU(previousParticipation); + state.currentEpochParticipation = ssz.altair.EpochParticipation.toViewDU(currentParticipation); + state.commit(); + return state; + }, + beforeEach: (state) => { + const pool = getAggregatedAttestationPool(state, numMissedVotes, numBadVotes); + return {state, pool}; + }, + fn: ({state, pool}) => { + pool.getAttestationsForBlock(forkchoice, state); + }, + }); + } +}); + +/** + * Fir dev purpose to find the best way to get not seen validators. + */ +describe.skip("getAttestationsForBlock aggregationBits intersectValues vs get", () => { + const runsFactor = 1000; + // As of Jan 2004 + const committeeLen = 450; + const aggregationBits = BitArray.fromBoolArray(Array.from({length: committeeLen}, () => true)); + const notSeenValidatorIndices = Array.from({length: committeeLen}, (_, i) => i); + itBench({ - id: "getAttestationsForBlock", - beforeEach: () => getAggregatedAttestationPool(originalState), - fn: (pool) => { - // logger.info("Number of attestations in pool", pool.getAll().length); - pool.getAttestationsForBlock(forkchoice, originalState); + id: "aggregationBits.intersectValues()", + fn: () => { + for (let i = 0; i < runsFactor; i++) { + aggregationBits.intersectValues(notSeenValidatorIndices); + } }, + runsFactor, + }); + + itBench({ + id: "aggregationBits.get()", + fn: () => { + for (let i = 0; i < runsFactor; i++) { + for (let j = 0; j < committeeLen; j++) { + aggregationBits.get(j); + } + } + }, + runsFactor, + }); + + itBench({ + id: "aggregationBits.get() with push()", + fn: () => { + for (let i = 0; i < runsFactor; i++) { + const arr: number[] = []; + for (let j = 0; j < committeeLen; j++) { + if (aggregationBits.get(j)) { + arr.push(j); + } + } + } + }, + runsFactor, }); }); -function getAggregatedAttestationPool(state: CachedBeaconStateAltair): AggregatedAttestationPool { +/** + * Create the pool with the following properties: + * - state: at slot n + * - all attestations at slot n - 1 are included in block but they are not enough + * - numMissedVotes: number of missed attestations/votes at every committee + * - numBadVotes: number of bad attestations/votes at every committee, they are not included in block because they are seen in the state + */ +function getAggregatedAttestationPool( + state: CachedBeaconStateAltair, + numMissedVotes: number, + numBadVotes: number +): AggregatedAttestationPool { const pool = new AggregatedAttestationPool(); for (let epochSlot = 0; epochSlot < SLOTS_PER_EPOCH; epochSlot++) { const slot = state.slot - 1 - epochSlot; @@ -145,31 +234,82 @@ function getAggregatedAttestationPool(state: CachedBeaconStateAltair): Aggregate epoch: state.currentJustifiedCheckpoint.epoch, root: state.currentJustifiedCheckpoint.root, }; + for (let committeeIndex = 0; committeeIndex < committeeCount; committeeIndex++) { - const attestation = { - aggregationBits: BitArray.fromBitLen(64), - data: { - slot: slot, - index: committeeIndex, - beaconBlockRoot: getBlockRootAtSlot(state, slot), - source: sourceCheckpoint, - target: { - epoch, - root: getBlockRootAtSlot(state, computeStartSlotAtEpoch(epoch)), - }, + const goodAttData = { + slot: slot, + index: committeeIndex, + beaconBlockRoot: getBlockRootAtSlot(state, slot), + source: sourceCheckpoint, + target: { + epoch, + root: getBlockRootAtSlot(state, computeStartSlotAtEpoch(epoch)), }, - signature: Buffer.alloc(96), }; + // for each good att data group, there are 4 versions of aggregation bits const committee = state.epochCtx.getBeaconCommittee(slot, committeeIndex); - // all attestation has full participation so getAttestationsForBlock() has to do a lot of filter - // aggregate_and_proof messages - pool.add( - attestation, - toHexString(ssz.phase0.AttestationData.hashTreeRoot(attestation.data)), - committee.length, - committee - ); + const committeeLen = committee.length; + const goodVoteBits = BitArray.fromBoolArray(Array.from({length: committeeLen}, () => true)); + // n first validators are totally missed + for (let i = 0; i < numMissedVotes; i++) { + goodVoteBits.set(i, false); + } + // n next validators vote for different att data + for (let i = 0; i < numBadVotes; i++) { + goodVoteBits.set(i + numMissedVotes, false); + } + + // there are 4 different versions of the good vote + for (const endingBits of [0b1000, 0b0100, 0b0010, 0b0001]) { + const aggregationBits = goodVoteBits.clone(); + aggregationBits.set(committeeLen - 1, Boolean(endingBits & 0b0001)); + aggregationBits.set(committeeLen - 2, Boolean(endingBits & 0b0010)); + aggregationBits.set(committeeLen - 3, Boolean(endingBits & 0b0100)); + aggregationBits.set(committeeLen - 4, Boolean(endingBits & 0b1000)); + + const attestation = { + aggregationBits, + data: goodAttData, + signature: Buffer.alloc(96), + }; + // all attestation has full participation so getAttestationsForBlock() has to do a lot of filter + // aggregate_and_proof messages + pool.add( + attestation, + toHexString(ssz.phase0.AttestationData.hashTreeRoot(attestation.data)), + committee.length, + committee + ); + } + + if (epochSlot === 0) { + // epochSlot === 0: attestations will be included in block but it's not enough for block + // epochSlot >= 1: no attestation will be included in block but the code still need to scan through them + continue; + } + + const zeroAggregationBits = BitArray.fromBoolArray(Array.from({length: committeeLen}, () => false)); + + // n first validator votes for n different bad votes, that makes n different att data in the same slot/index + // these votes/attestations will NOT be included in block as they are seen in the state + for (let i = 0; i < numBadVotes; i++) { + const attData = ssz.phase0.AttestationData.clone(goodAttData); + attData.beaconBlockRoot = getBlockRootAtSlot(state, slot - i - 1); + const aggregationBits = zeroAggregationBits.clone(); + aggregationBits.set(i + numMissedVotes, true); + const attestation = { + aggregationBits, + data: attData, + signature: Buffer.alloc(96), + }; + pool.add( + attestation, + toHexString(ssz.phase0.AttestationData.hashTreeRoot(attestation.data)), + committee.length, + committee + ); + } } } return pool; 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 48abfbc35675..00aa8a40168b 100644 --- a/packages/beacon-node/test/unit/chain/opPools/aggregatedAttestationPool.test.ts +++ b/packages/beacon-node/test/unit/chain/opPools/aggregatedAttestationPool.test.ts @@ -2,14 +2,15 @@ import type {SecretKey} from "@chainsafe/bls/types"; import bls from "@chainsafe/bls"; import {BitArray, fromHexString, toHexString} from "@chainsafe/ssz"; import {describe, it, expect, beforeEach, beforeAll, afterEach, vi} from "vitest"; -import {CachedBeaconStateAllForks} from "@lodestar/state-transition"; -import {SLOTS_PER_EPOCH} from "@lodestar/params"; +import {CachedBeaconStateAllForks, newFilledArray} from "@lodestar/state-transition"; +import {FAR_FUTURE_EPOCH, MAX_EFFECTIVE_BALANCE, SLOTS_PER_EPOCH} from "@lodestar/params"; import {ssz, phase0} from "@lodestar/types"; +import {CachedBeaconStateAltair} from "@lodestar/state-transition/src/types.js"; import {MockedForkChoice, getMockedForkChoice} from "../../../mocks/mockedBeaconChain.js"; import { AggregatedAttestationPool, aggregateInto, - getParticipationFn, + getNotSeenValidatorsFn, MatchingDataAttestationGroup, } from "../../../../src/chain/opPools/aggregatedAttestationPool.js"; import {InsertOutcome} from "../../../../src/chain/opPools/types.js"; @@ -18,6 +19,7 @@ import {generateCachedAltairState} from "../../../utils/state.js"; import {renderBitArray} from "../../../utils/render.js"; import {ZERO_HASH_HEX} from "../../../../src/constants/constants.js"; import {generateProtoBlock} from "../../../utils/typeGenerator.js"; +import {generateValidators} from "../../../utils/validator.js"; /** Valid signature of random data to prevent BLS errors */ const validSignature = fromHexString( @@ -29,15 +31,43 @@ describe("AggregatedAttestationPool", function () { const altairForkEpoch = 2020; const currentEpoch = altairForkEpoch + 10; const currentSlot = SLOTS_PER_EPOCH * currentEpoch; - const originalState = generateCachedAltairState({slot: currentSlot + 1}, altairForkEpoch); - let altairState: CachedBeaconStateAllForks; + const committeeIndex = 0; const attestation = ssz.phase0.Attestation.defaultValue(); attestation.data.slot = currentSlot; + attestation.data.index = committeeIndex; attestation.data.target.epoch = currentEpoch; const attDataRootHex = toHexString(ssz.phase0.AttestationData.hashTreeRoot(attestation.data)); - const committee = [0, 1, 2, 3]; + const validatorOpts = { + activationEpoch: 0, + effectiveBalance: MAX_EFFECTIVE_BALANCE, + withdrawableEpoch: FAR_FUTURE_EPOCH, + exitEpoch: FAR_FUTURE_EPOCH, + }; + // this makes a committee length of 4 + const vc = 64; + const committeeLength = 4; + const validators = generateValidators(vc, validatorOpts); + const originalState = generateCachedAltairState({slot: currentSlot + 1, validators}, altairForkEpoch); + const committee = originalState.epochCtx.getBeaconCommittee(currentSlot, committeeIndex); + expect(committee.length).toEqual(committeeLength); + // 0 and 1 in committee are fully participated + const epochParticipation = newFilledArray(vc, 0b111); + for (let i = 0; i < committeeLength; i++) { + if (i === 0 || i === 1) { + epochParticipation[committee[i]] = 0b111; + } else { + epochParticipation[committee[i]] = 0b000; + } + } + (originalState as CachedBeaconStateAltair).previousEpochParticipation = + ssz.altair.EpochParticipation.toViewDU(epochParticipation); + (originalState as CachedBeaconStateAltair).currentEpochParticipation = + ssz.altair.EpochParticipation.toViewDU(epochParticipation); + originalState.commit(); + let altairState: CachedBeaconStateAllForks; + let forkchoiceStub: MockedForkChoice; beforeEach(() => { @@ -53,9 +83,16 @@ describe("AggregatedAttestationPool", function () { it("getParticipationFn", () => { // previousEpochParticipation and currentEpochParticipation is created inside generateCachedState // 0 and 1 are fully participated - const participationFn = getParticipationFn(altairState); - const participation = participationFn(currentEpoch, committee); - expect(participation).toEqual(new Set([0, 1])); + const notSeenValidatorFn = getNotSeenValidatorsFn(altairState); + const participation = notSeenValidatorFn(currentEpoch, committee); + // seen attesting indices are 0, 1 => not seen are 2, 3 + expect(participation).toEqual( + // { + // validatorIndices: [null, null, committee[2], committee[3]], + // attestingIndices: new Set([2, 3]), + // } + new Set([2, 3]) + ); }); // previousEpochParticipation and currentEpochParticipation is created inside generateCachedState @@ -68,7 +105,7 @@ describe("AggregatedAttestationPool", function () { for (const {name, attestingBits, isReturned} of testCases) { it(name, function () { - const aggregationBits = new BitArray(new Uint8Array(attestingBits), 8); + const aggregationBits = new BitArray(new Uint8Array(attestingBits), committeeLength); pool.add( {...attestation, aggregationBits}, attDataRootHex, @@ -180,13 +217,14 @@ describe("MatchingDataAttestationGroup.add()", () => { describe("MatchingDataAttestationGroup.getAttestationsForBlock", () => { const testCases: { id: string; - seenAttestingBits: number[]; + notSeenAttestingBits: number[]; attestationsToAdd: {bits: number[]; notSeenAttesterCount: number}[]; }[] = [ // Note: attestationsToAdd MUST intersect in order to not be aggregated and distort the results { id: "All have attested", - seenAttestingBits: [0b11111111], + // same to seenAttestingBits: [0b11111111], + notSeenAttestingBits: [0b00000000], attestationsToAdd: [ {bits: [0b11111110], notSeenAttesterCount: 0}, {bits: [0b00000011], notSeenAttesterCount: 0}, @@ -194,7 +232,8 @@ describe("MatchingDataAttestationGroup.getAttestationsForBlock", () => { }, { id: "Some have attested", - seenAttestingBits: [0b11110001], // equals to indexes [ 0, 4, 5, 6, 7 ] + // same to seenAttestingBits: [0b11110001] + notSeenAttestingBits: [0b00001110], attestationsToAdd: [ {bits: [0b11111110], notSeenAttesterCount: 3}, {bits: [0b00000011], notSeenAttesterCount: 1}, @@ -202,7 +241,8 @@ describe("MatchingDataAttestationGroup.getAttestationsForBlock", () => { }, { id: "Non have attested", - seenAttestingBits: [0b00000000], + // same to seenAttestingBits: [0b00000000], + notSeenAttestingBits: [0b11111111], attestationsToAdd: [ {bits: [0b11111110], notSeenAttesterCount: 7}, {bits: [0b00000011], notSeenAttesterCount: 2}, @@ -213,7 +253,7 @@ describe("MatchingDataAttestationGroup.getAttestationsForBlock", () => { const attestationData = ssz.phase0.AttestationData.defaultValue(); const committee = linspace(0, 7); - for (const {id, seenAttestingBits, attestationsToAdd} of testCases) { + for (const {id, notSeenAttestingBits, attestationsToAdd} of testCases) { it(id, () => { const attestationGroup = new MatchingDataAttestationGroup(committee, attestationData); @@ -229,8 +269,19 @@ describe("MatchingDataAttestationGroup.getAttestationsForBlock", () => { attestationGroup.add({attestation, trueBitsCount: attestation.aggregationBits.getTrueBitIndexes().length}); } - const indices = new BitArray(new Uint8Array(seenAttestingBits), 8).intersectValues(committee); - const attestationsForBlock = attestationGroup.getAttestationsForBlock(new Set(indices)); + const notSeenAggBits = new BitArray(new Uint8Array(notSeenAttestingBits), 8); + // const notSeenValidatorIndices: (ValidatorIndex | null)[] = []; + const notSeenAttestingIndices = new Set(); + for (let i = 0; i < committee.length; i++) { + // notSeenValidatorIndices.push(notSeenAggBits.get(i) ? committee[i] : null); + if (notSeenAggBits.get(i)) { + notSeenAttestingIndices.add(i); + } + } + const attestationsForBlock = attestationGroup.getAttestationsForBlock( + // notSeenValidatorIndices, + notSeenAttestingIndices + ); for (const [i, {notSeenAttesterCount}] of attestationsToAdd.entries()) { const attestation = attestationsForBlock.find((a) => a.attestation === attestations[i]); From 0db50b929b97796f2e958c88054a271d849ff9f1 Mon Sep 17 00:00:00 2001 From: Julien Date: Thu, 1 Feb 2024 11:54:09 -0800 Subject: [PATCH 25/41] chore: improve browser support (#6384) * fix: remove unsupported syntax * fix: handle undefined process * chore: remove uneeded type --- packages/light-client/src/transport/rest.ts | 18 +++++++----------- packages/params/src/index.ts | 4 +++- packages/state-transition/src/util/sszBytes.ts | 4 ++-- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/light-client/src/transport/rest.ts b/packages/light-client/src/transport/rest.ts index ebbd8e52f691..2c63f2ea988a 100644 --- a/packages/light-client/src/transport/rest.ts +++ b/packages/light-client/src/transport/rest.ts @@ -1,25 +1,21 @@ import EventEmitter from "events"; -import StrictEventEmitter from "strict-event-emitter-types"; -import {allForks, SyncPeriod} from "@lodestar/types"; -import {Api, ApiError, routes} from "@lodestar/api"; -import {ForkName} from "@lodestar/params"; -import {LightClientTransport} from "./interface.js"; +import {type StrictEventEmitter} from "strict-event-emitter-types"; +import {type allForks, type SyncPeriod} from "@lodestar/types"; +import {type Api, ApiError, routes} from "@lodestar/api"; +import {type ForkName} from "@lodestar/params"; +import {type LightClientTransport} from "./interface.js"; export type LightClientRestEvents = { [routes.events.EventType.lightClientFinalityUpdate]: allForks.LightClientFinalityUpdate; [routes.events.EventType.lightClientOptimisticUpdate]: allForks.LightClientOptimisticUpdate; }; -type RestEvents = StrictEventEmitter; - -export class LightClientRestTransport extends (EventEmitter as {new (): RestEvents}) implements LightClientTransport { +export class LightClientRestTransport implements LightClientTransport { private controller = new AbortController(); private readonly eventEmitter: StrictEventEmitter = new EventEmitter(); private subscribedEventstream = false; - constructor(private readonly api: Api) { - super(); - } + constructor(private readonly api: Api) {} async getUpdates( startPeriod: SyncPeriod, diff --git a/packages/params/src/index.ts b/packages/params/src/index.ts index d111d090b8c3..6a95e3ca632e 100644 --- a/packages/params/src/index.ts +++ b/packages/params/src/index.ts @@ -28,7 +28,9 @@ presetStatus.frozen = true; * The active preset can be manually overridden with `setActivePreset` */ export const ACTIVE_PRESET = - userSelectedPreset ?? PresetName[process?.env?.LODESTAR_PRESET as PresetName] ?? PresetName.mainnet; + userSelectedPreset ?? + (typeof process !== "undefined" ? PresetName[process?.env?.LODESTAR_PRESET as PresetName] : undefined) ?? + PresetName.mainnet; export const activePreset = {...presets[ACTIVE_PRESET], ...userOverrides}; // These variables must be exported individually and explicitly diff --git a/packages/state-transition/src/util/sszBytes.ts b/packages/state-transition/src/util/sszBytes.ts index 25b65626a0dd..b5141e1673e5 100644 --- a/packages/state-transition/src/util/sszBytes.ts +++ b/packages/state-transition/src/util/sszBytes.ts @@ -37,14 +37,14 @@ export const VALIDATOR_BYTES_SIZE = 121; */ const SLOT_BYTES_POSITION_IN_STATE = 40; -export function getForkFromStateBytes(config: ChainForkConfig, bytes: Buffer | Uint8Array): ForkSeq { +export function getForkFromStateBytes(config: ChainForkConfig, bytes: Uint8Array): ForkSeq { const slot = bytesToInt(bytes.subarray(SLOT_BYTES_POSITION_IN_STATE, SLOT_BYTES_POSITION_IN_STATE + SLOT_BYTE_COUNT)); return config.getForkSeq(slot); } export function getStateTypeFromBytes( config: ChainForkConfig, - bytes: Buffer | Uint8Array + bytes: Uint8Array ): allForks.AllForksSSZTypes["BeaconState"] { const slot = getStateSlotFromBytes(bytes); return config.getForkTypes(slot).BeaconState; From 00dfa63413e9b2a57dbaea70ac7151ef134b0c05 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Thu, 1 Feb 2024 22:42:51 +0100 Subject: [PATCH 26/41] feat: add builder selection executionalways (#6370) --- docs/pages/validator-management/vc-configuration.md | 1 + packages/api/src/beacon/routes/validator.ts | 1 + packages/beacon-node/src/api/impl/validator/index.ts | 1 + .../test/unit/api/impl/validator/produceBlockV3.test.ts | 6 ++++++ packages/cli/src/cmds/validator/options.ts | 3 ++- packages/cli/src/util/proposerConfig.ts | 7 ++++--- packages/validator/src/services/validatorStore.ts | 1 + 7 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/pages/validator-management/vc-configuration.md b/docs/pages/validator-management/vc-configuration.md index a1077997cd77..f1fa720c7ee1 100644 --- a/docs/pages/validator-management/vc-configuration.md +++ b/docs/pages/validator-management/vc-configuration.md @@ -97,6 +97,7 @@ With produceBlockV3 (enabled automatically after the Deneb hard fork), the `--bu With Lodestar's `--builder.selection` validator options, you can select: - `maxprofit`: Default setting for Lodestar set at `--builder.boostFactor=100`. This default setting will always choose the more profitable block. Using this option, you may customize your `--builder.boostFactor` to your preference. Examples of its usage are below. +- `executionalways`: An alias of `--builder.boostFactor=0`, which will select the local execution block, unless it fails to produce due to an error or a delay in the response from the execution client. - `executiononly`: Beacon node will be requested to produce local execution block even if builder relays are configured. This option will always select the local execution block and will error if it couldn't produce one. - `builderalways`: An alias of `--builder.boostFactor=18446744073709551615` (2**64 - 1), which will select the builder block, unless the builder block fails to produce. The builder block may fail to produce if it's not available, not timely or there is an indication of censorship via `shouldOverrideBuilder` from the execution payload response. - `builderonly`: Generally used for distributed validators (DVs). No execution block production will be triggered. Therefore, if a builder block is not produced, the API will fail and _no block will be produced_. diff --git a/packages/api/src/beacon/routes/validator.ts b/packages/api/src/beacon/routes/validator.ts index 09fbd9de3162..5b6fa7797d88 100644 --- a/packages/api/src/beacon/routes/validator.ts +++ b/packages/api/src/beacon/routes/validator.ts @@ -43,6 +43,7 @@ import {ExecutionOptimistic} from "./beacon/block.js"; export enum BuilderSelection { BuilderAlways = "builderalways", + ExecutionAlways = "executionalways", MaxProfit = "maxprofit", /** Only activate builder flow for DVT block proposal protocols */ BuilderOnly = "builderonly", diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index e795d1c5afad..e6dac77b3a7c 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -612,6 +612,7 @@ export function getValidatorApi({ break; } + case routes.validator.BuilderSelection.ExecutionAlways: case routes.validator.BuilderSelection.ExecutionOnly: { executionPayloadSource = ProducedBlockSource.engine; break; 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 4484bcf03563..ba0267fc5810 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 @@ -49,6 +49,12 @@ describe("api/validator - produceBlockV3", function () { [routes.validator.BuilderSelection.BuilderAlways, 1, 1, 1, true, "engine"], [routes.validator.BuilderSelection.BuilderAlways, 1, null, 1, true, "builder"], + [routes.validator.BuilderSelection.ExecutionAlways, 2, 1, 0, false, "engine"], + [routes.validator.BuilderSelection.ExecutionAlways, 0, 1, 1, false, "engine"], + [routes.validator.BuilderSelection.ExecutionAlways, 0, null, 0, false, "builder"], + [routes.validator.BuilderSelection.ExecutionAlways, null, 0, 1, false, "engine"], + [routes.validator.BuilderSelection.ExecutionAlways, 1, 1, 1, true, "engine"], + [routes.validator.BuilderSelection.BuilderOnly, 0, 2, 0, false, "builder"], [routes.validator.BuilderSelection.ExecutionOnly, 2, 0, 1, false, "engine"], [routes.validator.BuilderSelection.BuilderOnly, 1, 1, 0, true, "builder"], diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index ecc8ad32ca87..20bfc106d258 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -242,7 +242,8 @@ export const validatorOptions: CliCommandOptions = { "builder.selection": { type: "string", - description: "Builder block selection strategy `maxprofit`, `builderalways`, `builderonly` or `executiononly`", + description: + "Builder block selection strategy `maxprofit`, `builderalways`, `builderonly`, `executionalways`, or `executiononly`", defaultDescription: `${defaultOptions.builderSelection}`, group: "builder", }, diff --git a/packages/cli/src/util/proposerConfig.ts b/packages/cli/src/util/proposerConfig.ts index 661c81ee63af..ae56cc45513a 100644 --- a/packages/cli/src/util/proposerConfig.ts +++ b/packages/cli/src/util/proposerConfig.ts @@ -8,7 +8,6 @@ import {routes} from "@lodestar/api"; import {parseFeeRecipient} from "./feeRecipient.js"; import {readFile} from "./file.js"; -import {YargsError} from "./index.js"; type ProposerConfig = ValidatorProposerConfig["defaultConfig"]; @@ -114,10 +113,12 @@ export function parseBuilderSelection(builderSelection?: string): routes.validat break; case "builderonly": break; + case "executionalways": + break; case "executiononly": break; default: - throw new YargsError("Invalid input for builder selection, check help"); + throw Error("Invalid input for builder selection, check help"); } } return builderSelection as routes.validator.BuilderSelection; @@ -127,7 +128,7 @@ export function parseBuilderBoostFactor(boostFactor?: string): bigint | undefine if (boostFactor === undefined) return; if (!/^\d+$/.test(boostFactor)) { - throw new YargsError("Invalid input for builder boost factor, must be a valid number without decimals"); + throw Error("Invalid input for builder boost factor, must be a valid number without decimals"); } return BigInt(boostFactor); diff --git a/packages/validator/src/services/validatorStore.ts b/packages/validator/src/services/validatorStore.ts index 03811062c2ad..d1474e7fdd28 100644 --- a/packages/validator/src/services/validatorStore.ts +++ b/packages/validator/src/services/validatorStore.ts @@ -277,6 +277,7 @@ export class ValidatorStore { boostFactor = MAX_BUILDER_BOOST_FACTOR; break; + case routes.validator.BuilderSelection.ExecutionAlways: case routes.validator.BuilderSelection.ExecutionOnly: boostFactor = BigInt(0); } From ac4e714ef38f663a5e7dcfe916ce3a027e1f3ff9 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Mon, 5 Feb 2024 15:52:15 +0100 Subject: [PATCH 27/41] refactor: update the block production race (#6241) * Update the promise race implementation * Update block production race * Fix spelling * Work on feedback * Update the test file name * Update the promise tests * Update util to switch * chore: add early return on censoring builder or 0 builder boost * Update the promise to extended promise * Update the builder flow * Fix the types * Fix lint errors * Simplify logging * Improve log messages for block values * Update the promise to be typesafe * Update the validator implementation * Restructure test file for better review * Fix lint errors * Fix lint error * Make the tyep more flexible * Fix flaky tests * Improve log message * Simplify implementation * Update log message function * chore: add review feedback * chore: fix linter error * chore: address PR comments * Update packages/beacon-node/src/api/impl/validator/index.ts Co-authored-by: Nico Flaig * chore: address PR comments * chore: clean up selectBlockProductionSource * Fix unit tests * Add support for routes.validator.BuilderSelection.ExecutionOnly * Fix unit tests * Increase the timeout for e2e env * Apply suggestions from code review Co-authored-by: Nico Flaig * Increase the timeout for e2e env * Revert e2e timeout --------- Co-authored-by: Cayman Co-authored-by: Nico Flaig --- .../src/api/impl/validator/index.ts | 346 +++++++++--------- .../src/api/impl/validator/utils.ts | 32 +- packages/utils/src/format.ts | 27 ++ packages/utils/src/promise.ts | 212 ++++++----- packages/utils/src/types.ts | 6 + packages/utils/test/unit/format.test.ts | 23 ++ packages/utils/test/unit/promise.test.ts | 73 ++++ packages/utils/test/unit/promiserace.test.ts | 84 ++--- packages/validator/src/services/block.ts | 3 +- packages/validator/src/util/format.ts | 9 - .../validator/test/unit/utils/format.test.ts | 21 -- 11 files changed, 479 insertions(+), 357 deletions(-) create mode 100644 packages/utils/test/unit/format.test.ts create mode 100644 packages/utils/test/unit/promise.test.ts delete mode 100644 packages/validator/test/unit/utils/format.test.ts diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index e6dac77b3a7c..0b45540c791e 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -35,7 +35,7 @@ import { phase0, } from "@lodestar/types"; import {ExecutionStatus} from "@lodestar/fork-choice"; -import {toHex, racePromisesWithCutoff, RaceEvent} from "@lodestar/utils"; +import {toHex, resolveOrRacePromises, prettyWeiToEth} from "@lodestar/utils"; import { AttestationError, AttestationErrorCode, @@ -57,7 +57,7 @@ import {getValidatorStatus} 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"; -import {computeSubnetForCommitteesAtSlot, getPubkeysForIndices} from "./utils.js"; +import {computeSubnetForCommitteesAtSlot, getPubkeysForIndices, selectBlockProductionSource} from "./utils.js"; /** * If the node is within this many epochs from the head, we declare it to be synced regardless of @@ -177,6 +177,35 @@ export function getValidatorApi({ return computeEpochAtSlot(getCurrentSlot(config, chain.genesisTime - MAX_API_CLOCK_DISPARITY_SEC)); } + function getBlockValueLogInfo( + block: {executionPayloadValue: bigint; consensusBlockValue: bigint}, + source?: ProducedBlockSource + ): Record { + const executionValue = block.executionPayloadValue; + const consensusValue = block.consensusBlockValue; + const totalValue = executionValue + consensusValue; + + if (source == null) { + return { + executionPayloadValue: prettyWeiToEth(executionValue, true), + consensusBlockValue: prettyWeiToEth(consensusValue, true), + blockTotalValue: prettyWeiToEth(totalValue, true), + }; + } else if (source === ProducedBlockSource.builder) { + return { + builderExecutionPayloadValue: prettyWeiToEth(executionValue, true), + builderConsensusBlockValue: prettyWeiToEth(consensusValue, true), + builderBlockTotalValue: prettyWeiToEth(totalValue, true), + }; + } else { + return { + engineExecutionPayloadValue: prettyWeiToEth(executionValue, true), + engineConsensusBlockValue: prettyWeiToEth(consensusValue, true), + engineBlockTotalValue: prettyWeiToEth(totalValue, true), + }; + } + } + /** * This function is called 1s before next epoch, usually at that time PrepareNextSlotScheduler finishes * so we should have checkpoint state, otherwise wait for up to the slot 1 of epoch. @@ -472,11 +501,28 @@ export function getValidatorApi({ chain.executionBuilder !== undefined && builderSelection !== routes.validator.BuilderSelection.ExecutionOnly; + // At any point either the builder or execution or both flows should be active. + // + // Ideally such a scenario should be prevented on startup, but proposerSettingsFile or keymanager + // configurations could cause a validator pubkey to have builder disabled with builder selection builder only + // (TODO: independently make sure such an options update is not successful for a validator pubkey) + // + // So if builder is disabled ignore builder selection of builder only if caused by user mistake + // https://github.com/ChainSafe/lodestar/issues/6338 + const isEngineEnabled = !isBuilderEnabled || builderSelection !== routes.validator.BuilderSelection.BuilderOnly; + + if (!isEngineEnabled && !isBuilderEnabled) { + throw Error( + `Internal Error: Neither builder nor execution proposal flow activated isBuilderEnabled=${isBuilderEnabled} builderSelection=${builderSelection}` + ); + } + const loggerContext = { fork, builderSelection, slot, isBuilderEnabled, + isEngineEnabled, strictFeeRecipientCheck, // winston logger doesn't like bigint builderBoostFactor: `${builderBoostFactor}`, @@ -490,197 +536,151 @@ export function getValidatorApi({ }); logger.debug("Produced common block body", loggerContext); + logger.verbose("Block production race (builder vs execution) starting", { + ...loggerContext, + cutoffMs: BLOCK_PRODUCTION_RACE_CUTOFF_MS, + timeoutMs: BLOCK_PRODUCTION_RACE_TIMEOUT_MS, + }); + + // use abort controller to stop waiting for both block sources + const controller = new AbortController(); + // Start calls for building execution and builder blocks - const blindedBlockPromise = isBuilderEnabled - ? // can't do fee recipient checks as builder bid doesn't return feeRecipient as of now - produceBuilderBlindedBlock(slot, randaoReveal, graffiti, { + + const builderPromise = isBuilderEnabled + ? produceBuilderBlindedBlock(slot, randaoReveal, graffiti, { feeRecipient, + // can't do fee recipient checks as builder bid doesn't return feeRecipient as of now + strictFeeRecipientCheck: false, // skip checking and recomputing head in these individual produce calls skipHeadChecksAndUpdate: true, commonBlockBody, - }).catch((e) => { - logger.error("produceBuilderBlindedBlock failed to produce block", {slot}, e); - return null; }) - : null; - - const fullBlockPromise = - // At any point either the builder or execution or both flows should be active. - // - // Ideally such a scenario should be prevented on startup, but proposerSettingsFile or keymanager - // configurations could cause a validator pubkey to have builder disabled with builder selection builder only - // (TODO: independently make sure such an options update is not successful for a validator pubkey) - // - // So if builder is disabled ignore builder selection of builderonly if caused by user mistake - !isBuilderEnabled || builderSelection !== routes.validator.BuilderSelection.BuilderOnly - ? // TODO deneb: builderSelection needs to be figured out if to be done beacon side - // || builderSelection !== BuilderSelection.BuilderOnly - produceEngineFullBlockOrContents(slot, randaoReveal, graffiti, { - feeRecipient, - strictFeeRecipientCheck, - // skip checking and recomputing head in these individual produce calls - skipHeadChecksAndUpdate: true, - commonBlockBody, - }).catch((e) => { - logger.error("produceEngineFullBlockOrContents failed to produce block", {slot}, e); - return null; - }) - : null; - - let blindedBlock, fullBlock; - if (blindedBlockPromise !== null && fullBlockPromise !== null) { - // reference index of promises in the race - const promisesOrder = [ProducedBlockSource.builder, ProducedBlockSource.engine]; - [blindedBlock, fullBlock] = await racePromisesWithCutoff< - | ((routes.validator.ProduceBlockOrContentsRes | routes.validator.ProduceBlindedBlockRes) & { - shouldOverrideBuilder?: boolean; - }) - | null - >( - [blindedBlockPromise, fullBlockPromise], - BLOCK_PRODUCTION_RACE_CUTOFF_MS, - BLOCK_PRODUCTION_RACE_TIMEOUT_MS, - // Callback to log the race events for better debugging capability - (event: RaceEvent, delayMs: number, index?: number) => { - const eventRef = index !== undefined ? {source: promisesOrder[index]} : {}; - logger.verbose("Block production race (builder vs execution)", { - event, - ...eventRef, - delayMs, - cutoffMs: BLOCK_PRODUCTION_RACE_CUTOFF_MS, - timeoutMs: BLOCK_PRODUCTION_RACE_TIMEOUT_MS, - slot, - }); - } - ); - if (blindedBlock instanceof Error) { - // error here means race cutoff exceeded - logger.error("Failed to produce builder block", {slot}, blindedBlock); - blindedBlock = null; - } - if (fullBlock instanceof Error) { - logger.error("Failed to produce execution block", {slot}, fullBlock); - fullBlock = null; - } - } else if (blindedBlockPromise !== null && fullBlockPromise === null) { - blindedBlock = await blindedBlockPromise; - fullBlock = null; - } else if (blindedBlockPromise === null && fullBlockPromise !== null) { - blindedBlock = null; - fullBlock = await fullBlockPromise; - } else { - throw Error( - `Internal Error: Neither builder nor execution proposal flow activated isBuilderEnabled=${isBuilderEnabled} builderSelection=${builderSelection}` - ); - } + : Promise.reject(new Error("Builder disabled")); - const builderPayloadValue = blindedBlock?.executionPayloadValue ?? BigInt(0); - const enginePayloadValue = fullBlock?.executionPayloadValue ?? BigInt(0); - const consensusBlockValueBuilder = blindedBlock?.consensusBlockValue ?? BigInt(0); - const consensusBlockValueEngine = fullBlock?.consensusBlockValue ?? BigInt(0); - - const blockValueBuilder = builderPayloadValue + consensusBlockValueBuilder; // Total block value is in wei - const blockValueEngine = enginePayloadValue + consensusBlockValueEngine; // Total block value is in wei - - let executionPayloadSource: ProducedBlockSource | null = null; - const shouldOverrideBuilder = fullBlock?.shouldOverrideBuilder ?? false; - - // handle the builder override case separately - if (shouldOverrideBuilder === true) { - executionPayloadSource = ProducedBlockSource.engine; - logger.info("Selected engine block as censorship suspected in builder blocks", { - // winston logger doesn't like bigint - enginePayloadValue: `${enginePayloadValue}`, - consensusBlockValueEngine: `${consensusBlockValueEngine}`, - blockValueEngine: `${blockValueEngine}`, - shouldOverrideBuilder, - slot, - }); - } else if (fullBlock && blindedBlock) { - switch (builderSelection) { - case routes.validator.BuilderSelection.MaxProfit: { + const enginePromise = isEngineEnabled + ? produceEngineFullBlockOrContents(slot, randaoReveal, graffiti, { + feeRecipient, + strictFeeRecipientCheck, + // skip checking and recomputing head in these individual produce calls + skipHeadChecksAndUpdate: true, + commonBlockBody, + }).then((engineBlock) => { + // Once the engine returns a block, in the event of either: + // - suspected builder censorship + // - builder boost factor set to 0 or builder selection `executionalways` + // we don't need to wait for builder block as engine block will always be selected if ( - // explicitly handle the two special values mentioned in spec for builder preferred / engine preferred - builderBoostFactor !== MAX_BUILDER_BOOST_FACTOR && - (builderBoostFactor === BigInt(0) || - blockValueEngine >= (blockValueBuilder * builderBoostFactor) / BigInt(100)) + engineBlock.shouldOverrideBuilder || + builderBoostFactor === BigInt(0) || + builderSelection === routes.validator.BuilderSelection.ExecutionAlways ) { - executionPayloadSource = ProducedBlockSource.engine; - } else { - executionPayloadSource = ProducedBlockSource.builder; + controller.abort(); } - break; - } + return engineBlock; + }) + : Promise.reject(new Error("Engine disabled")); - case routes.validator.BuilderSelection.ExecutionAlways: - case routes.validator.BuilderSelection.ExecutionOnly: { - executionPayloadSource = ProducedBlockSource.engine; - break; - } + const [builder, engine] = await resolveOrRacePromises([builderPromise, enginePromise], { + resolveTimeoutMs: BLOCK_PRODUCTION_RACE_CUTOFF_MS, + raceTimeoutMs: BLOCK_PRODUCTION_RACE_TIMEOUT_MS, + signal: controller.signal, + }); - // For everything else just select the builder - default: { - executionPayloadSource = ProducedBlockSource.builder; - } - } - logger.info(`Selected executionPayloadSource=${executionPayloadSource} block`, { - builderSelection, - // winston logger doesn't like bigint - builderBoostFactor: `${builderBoostFactor}`, - enginePayloadValue: `${enginePayloadValue}`, - builderPayloadValue: `${builderPayloadValue}`, - consensusBlockValueEngine: `${consensusBlockValueEngine}`, - consensusBlockValueBuilder: `${consensusBlockValueBuilder}`, - blockValueEngine: `${blockValueEngine}`, - blockValueBuilder: `${blockValueBuilder}`, - shouldOverrideBuilder, - slot, - }); - } else if (fullBlock && !blindedBlock) { - executionPayloadSource = ProducedBlockSource.engine; - logger.info("Selected engine block: no builder block produced", { - // winston logger doesn't like bigint - enginePayloadValue: `${enginePayloadValue}`, - consensusBlockValueEngine: `${consensusBlockValueEngine}`, - blockValueEngine: `${blockValueEngine}`, - shouldOverrideBuilder, - slot, + if (builder.status === "pending" && engine.status === "pending") { + throw Error("Builder and engine both failed to produce the block within timeout"); + } + + if (builder.status === "rejected" && engine.status === "rejected") { + throw Error("Builder and engine both failed to produce the block"); + } + + if (engine.status === "rejected" && isEngineEnabled) { + logger.warn( + "Engine failed to produce the block", + { + ...loggerContext, + durationMs: engine.durationMs, + }, + engine.reason + ); + } + + if (builder.status === "rejected" && isBuilderEnabled) { + logger.warn( + "Builder failed to produce the block", + { + ...loggerContext, + durationMs: builder.durationMs, + }, + builder.reason + ); + } + + // handle shouldOverrideBuilder separately + if (engine.status === "fulfilled" && engine.value.shouldOverrideBuilder) { + logger.info("Selected engine block: censorship suspected in builder blocks", { + ...loggerContext, + durationMs: engine.durationMs, + shouldOverrideBuilder: engine.value.shouldOverrideBuilder, + ...getBlockValueLogInfo(engine.value), }); - } else if (blindedBlock && !fullBlock) { - executionPayloadSource = ProducedBlockSource.builder; + + return {...engine.value, executionPayloadBlinded: false, executionPayloadSource: ProducedBlockSource.engine}; + } + + if (builder.status === "fulfilled" && engine.status !== "fulfilled") { logger.info("Selected builder block: no engine block produced", { - // winston logger doesn't like bigint - builderPayloadValue: `${builderPayloadValue}`, - consensusBlockValueBuilder: `${consensusBlockValueBuilder}`, - blockValueBuilder: `${blockValueBuilder}`, - shouldOverrideBuilder, - slot, + ...loggerContext, + durationMs: builder.durationMs, + ...getBlockValueLogInfo(builder.value), }); + + return {...builder.value, executionPayloadBlinded: true, executionPayloadSource: ProducedBlockSource.builder}; } - if (executionPayloadSource === null) { - throw Error(`Failed to produce engine or builder block for slot=${slot}`); + if (engine.status === "fulfilled" && builder.status !== "fulfilled") { + logger.info("Selected engine block: no builder block produced", { + ...loggerContext, + durationMs: engine.durationMs, + ...getBlockValueLogInfo(engine.value), + }); + + return {...engine.value, executionPayloadBlinded: false, executionPayloadSource: ProducedBlockSource.engine}; } - if (executionPayloadSource === ProducedBlockSource.engine) { - return { - ...fullBlock, - executionPayloadBlinded: false, - executionPayloadSource, - } as routes.validator.ProduceBlockOrContentsRes & { - executionPayloadBlinded: false; - executionPayloadSource: ProducedBlockSource; - }; - } else { - return { - ...blindedBlock, - executionPayloadBlinded: true, - executionPayloadSource, - } as routes.validator.ProduceBlindedBlockRes & { - executionPayloadBlinded: true; - executionPayloadSource: ProducedBlockSource; - }; + if (engine.status === "fulfilled" && builder.status === "fulfilled") { + const executionPayloadSource = selectBlockProductionSource({ + builderBlockValue: builder.value.executionPayloadValue + builder.value.consensusBlockValue, + engineBlockValue: engine.value.executionPayloadValue + engine.value.consensusBlockValue, + builderBoostFactor, + builderSelection, + }); + + logger.info(`Selected ${executionPayloadSource} block`, { + ...loggerContext, + engineDurationMs: engine.durationMs, + ...getBlockValueLogInfo(engine.value, ProducedBlockSource.engine), + builderDurationMs: builder.durationMs, + ...getBlockValueLogInfo(builder.value, ProducedBlockSource.builder), + }); + + if (executionPayloadSource === ProducedBlockSource.engine) { + return { + ...engine.value, + executionPayloadBlinded: false, + executionPayloadSource, + }; + } else { + return { + ...builder.value, + executionPayloadBlinded: true, + executionPayloadSource, + }; + } } + + throw Error("Unreachable error occurred during the builder and execution block production"); }; const produceBlock: ServerApi["produceBlock"] = async function produceBlock( diff --git a/packages/beacon-node/src/api/impl/validator/utils.ts b/packages/beacon-node/src/api/impl/validator/utils.ts index 86ea223d59ab..8932f8951cf4 100644 --- a/packages/beacon-node/src/api/impl/validator/utils.ts +++ b/packages/beacon-node/src/api/impl/validator/utils.ts @@ -1,6 +1,8 @@ import {BeaconStateAllForks, computeSlotsSinceEpochStart} from "@lodestar/state-transition"; import {ATTESTATION_SUBNET_COUNT} from "@lodestar/params"; -import {BLSPubkey, CommitteeIndex, Slot, ValidatorIndex} from "@lodestar/types"; +import {routes} from "@lodestar/api"; +import {BLSPubkey, CommitteeIndex, ProducedBlockSource, Slot, ValidatorIndex} from "@lodestar/types"; +import {MAX_BUILDER_BOOST_FACTOR} from "@lodestar/validator"; export function computeSubnetForCommitteesAtSlot( slot: Slot, @@ -41,3 +43,31 @@ export function getPubkeysForIndices( return pubkeys; } + +export function selectBlockProductionSource({ + builderSelection, + engineBlockValue, + builderBlockValue, + builderBoostFactor, +}: { + builderSelection: routes.validator.BuilderSelection; + engineBlockValue: bigint; + builderBlockValue: bigint; + builderBoostFactor: bigint; +}): ProducedBlockSource { + switch (builderSelection) { + case routes.validator.BuilderSelection.ExecutionAlways: + case routes.validator.BuilderSelection.ExecutionOnly: + return ProducedBlockSource.engine; + + case routes.validator.BuilderSelection.MaxProfit: + return builderBoostFactor !== MAX_BUILDER_BOOST_FACTOR && + (builderBoostFactor === BigInt(0) || engineBlockValue >= (builderBlockValue * builderBoostFactor) / BigInt(100)) + ? ProducedBlockSource.engine + : ProducedBlockSource.builder; + + case routes.validator.BuilderSelection.BuilderAlways: + case routes.validator.BuilderSelection.BuilderOnly: + return ProducedBlockSource.builder; + } +} diff --git a/packages/utils/src/format.ts b/packages/utils/src/format.ts index 6a88ead41490..cf2352a4fbaa 100644 --- a/packages/utils/src/format.ts +++ b/packages/utils/src/format.ts @@ -1,4 +1,5 @@ import {toHexString} from "./bytes.js"; +import {ETH_TO_WEI} from "./ethConversion.js"; /** * Format bytes as `0x1234…1234` @@ -27,3 +28,29 @@ export function truncBytes(root: Uint8Array | string): string { const str = typeof root === "string" ? root : toHexString(root); return str.slice(0, 14); } + +/** + * Format a bigint value as a decimal string + */ +export function formatBigDecimal(numerator: bigint, denominator: bigint, maxDecimalFactor: bigint): string { + const full = numerator / denominator; + const fraction = ((numerator - full * denominator) * maxDecimalFactor) / denominator; + + // zeros to be added post decimal are number of zeros in maxDecimalFactor - number of digits in fraction + const zerosPostDecimal = String(maxDecimalFactor).length - 1 - String(fraction).length; + return `${full}.${"0".repeat(zerosPostDecimal)}${fraction}`; +} + +// display upto 5 decimal places +const MAX_DECIMAL_FACTOR = BigInt("100000"); + +/** + * Format wei as ETH, with up to 5 decimals + * + * if suffix is true, append ' ETH' + */ +export function prettyWeiToEth(wei: bigint, suffix = false): string { + let eth = formatBigDecimal(wei, ETH_TO_WEI, MAX_DECIMAL_FACTOR); + if (suffix) eth += " ETH"; + return eth; +} diff --git a/packages/utils/src/promise.ts b/packages/utils/src/promise.ts index 51e1cdbaf1e3..ba63854e9e85 100644 --- a/packages/utils/src/promise.ts +++ b/packages/utils/src/promise.ts @@ -1,4 +1,6 @@ +import {ErrorAborted, TimeoutError} from "./errors.js"; import {sleep} from "./sleep.js"; +import {ArrayToTuple, NonEmptyArray} from "./types.js"; /** * While promise t is not finished, call function `fn` per `interval` @@ -25,115 +27,129 @@ export async function callFnWhenAwait( return t; } -enum PromiseStatus { - resolved, - rejected, - pending, -} - -type PromiseState = - | {status: PromiseStatus.resolved; value: T} - | {status: PromiseStatus.rejected; value: Error} - | {status: PromiseStatus.pending; value: null}; - -function mapStatusesToResponses(promisesStates: PromiseState[]): (Error | T)[] { - return promisesStates.map((pmStatus) => { - switch (pmStatus.status) { - case PromiseStatus.resolved: - return pmStatus.value; - case PromiseStatus.rejected: - return pmStatus.value; - case PromiseStatus.pending: - return Error("pending"); +export type PromiseResult = { + promise: Promise; +} & ( + | { + status: "pending"; } - }); -} + | { + status: "fulfilled"; + value: T; + durationMs: number; + } + | { + status: "rejected"; + reason: Error; + durationMs: number; + } +); +export type PromiseFulfilledResult = PromiseResult & {status: "fulfilled"}; +export type PromiseRejectedResult = PromiseResult & {status: "rejected"}; -export enum RaceEvent { - /** all reject/resolve before cutoff */ - precutoff = "precutoff-return", - /** cutoff reached as some were pending till cutoff **/ - cutoff = "cutoff-reached", - /** atleast one resolved till cutoff so no race required */ - resolvedatcutoff = "resolved-at-cutoff", - /** if none reject/resolve before cutoff but one resolves or all reject before timeout */ - pretimeout = "pretimeout-return", - /** timeout reached as none resolved and some were pending till timeout*/ - timeout = "timeout-reached", +/** + * Wrap a promise to an object to track the status and value of the promise + */ +export function wrapPromise(promise: PromiseLike): PromiseResult { + const startedAt = Date.now(); + + const result = { + promise: promise.then( + (value) => { + result.status = "fulfilled"; + (result as PromiseFulfilledResult).value = value; + (result as PromiseFulfilledResult).durationMs = Date.now() - startedAt; + return value; + }, + (reason: unknown) => { + result.status = "rejected"; + (result as PromiseRejectedResult).reason = reason as Error; + (result as PromiseRejectedResult).durationMs = Date.now() - startedAt; + throw reason; + } + ), + status: "pending", + } as PromiseResult; - // events for the promises for better tracking - /** promise resolved */ - resolved = "resolved", - /** promise rejected */ - rejected = "rejected", + return result; } /** - * Wait for promises to resolve till cutoff and then race them beyond the cutoff with an overall timeout - * @return resolved values or rejections or still pending errors corresponding to input promises + * ArrayToTuple converts an `Array` to `[T, ...T]` + * + * eg: `[1, 2, 3]` from type `number[]` to `[number, number, number]` */ -export async function racePromisesWithCutoff( - promises: Promise[], - cutoffMs: number, - timeoutMs: number, - eventCb: (event: RaceEvent, delayMs: number, index?: number) => void -): Promise<(Error | T)[]> { - // start the cutoff and timeout timers - let cutoffObserved = false; - const cutoffPromise = sleep(cutoffMs).then(() => { - cutoffObserved = true; - }); - let timeoutObserved = false; - const timeoutPromise = sleep(timeoutMs).then(() => { - timeoutObserved = true; - }); - const startTime = Date.now(); +type ReturnPromiseWithTuple>> = { + [Index in keyof ArrayToTuple]: PromiseResult>; +}; - // Track promises status and resolved values/rejected errors - // Even if the promises reject with the following decoration promises will not throw - const promisesStates = [] as PromiseState[]; - promises.forEach((promise, index) => { - promisesStates[index] = {status: PromiseStatus.pending, value: null}; - promise - .then((value) => { - eventCb(RaceEvent.resolved, Date.now() - startTime, index); - promisesStates[index] = {status: PromiseStatus.resolved, value}; - }) - .catch((e: Error) => { - eventCb(RaceEvent.rejected, Date.now() - startTime, index); - promisesStates[index] = {status: PromiseStatus.rejected, value: e}; - }); - }); +/** + * Two phased approach for resolving promises: + * - first wait `resolveTimeoutMs` or until all promises settle + * - then wait `raceTimeoutMs - resolveTimeoutMs` or until at least a single promise resolves + * + * Returns a list of promise results, see `PromiseResult` + */ +export async function resolveOrRacePromises>>( + promises: T, + { + resolveTimeoutMs, + raceTimeoutMs, + signal, + }: { + resolveTimeoutMs: number; + raceTimeoutMs: number; + signal?: AbortSignal; + } +): Promise> | never { + if (raceTimeoutMs <= resolveTimeoutMs) { + throw new Error("Race time must be greater than resolve time"); + } + const resolveTimeoutError = new TimeoutError( + `Given promises can't be resolved within resolveTimeoutMs=${resolveTimeoutMs}` + ); + const raceTimeoutError = new TimeoutError( + `Not a any single promise be resolved in given raceTimeoutMs=${raceTimeoutMs}` + ); - // Wait till cutoff time unless all original promises resolve/reject early - await Promise.allSettled(promises.map((promise) => Promise.race([promise, cutoffPromise]))); - if (cutoffObserved) { - // If any is resolved, then just simply return as we are post cutoff - const anyResolved = promisesStates.reduce( - (acc, pmState) => acc || pmState.status === PromiseStatus.resolved, - false - ); - if (anyResolved) { - eventCb(RaceEvent.resolvedatcutoff, Date.now() - startTime); - return mapStatusesToResponses(promisesStates); - } else { - eventCb(RaceEvent.cutoff, Date.now() - startTime); + const promiseResults = promises.map((p) => wrapPromise(p)) as ReturnPromiseWithTuple; + promises = (promiseResults as PromiseResult[]).map((p) => p.promise) as unknown as T; + + try { + await Promise.race([ + Promise.allSettled(promises), + sleep(resolveTimeoutMs, signal).then(() => { + throw resolveTimeoutError; + }), + ]); + + return promiseResults; + } catch (err) { + if (err instanceof ErrorAborted) { + return promiseResults; + } + if (err !== resolveTimeoutError) { + throw err; } - } else { - eventCb(RaceEvent.precutoff, Date.now() - startTime); - return mapStatusesToResponses(promisesStates); } - // Post deadline resolve with any of the promise or all rejected before timeout - await Promise.any(promises.map((promise) => Promise.race([promise, timeoutPromise]))).catch( - // just ignore if all reject as we will returned mapped rejections - // eslint-disable-next-line @typescript-eslint/no-empty-function - (_e) => {} - ); - if (timeoutObserved) { - eventCb(RaceEvent.timeout, Date.now() - startTime); - } else { - eventCb(RaceEvent.pretimeout, Date.now() - startTime); + try { + await Promise.race([ + Promise.any(promises), + sleep(raceTimeoutMs - resolveTimeoutMs, signal).then(() => { + throw raceTimeoutError; + }), + ]); + + return promiseResults; + } catch (err) { + if (err instanceof ErrorAborted) { + return promiseResults; + } + if (err !== raceTimeoutError && !(err instanceof AggregateError)) { + throw err; + } } - return mapStatusesToResponses(promisesStates); + + return promiseResults; } diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts index f302c9a4c80c..cf07331e4456 100644 --- a/packages/utils/src/types.ts +++ b/packages/utils/src/types.ts @@ -14,3 +14,9 @@ export type RecursivePartial = { export function bnToNum(bn: bigint): number { return Number(bn); } + +export type NonEmptyArray = [T, ...T[]]; + +export type ArrayToTuple> = { + [Index in keyof Tuple]: Tuple[Index]; +}; diff --git a/packages/utils/test/unit/format.test.ts b/packages/utils/test/unit/format.test.ts new file mode 100644 index 000000000000..11e8b89cb7a1 --- /dev/null +++ b/packages/utils/test/unit/format.test.ts @@ -0,0 +1,23 @@ +import {describe, it, expect} from "vitest"; +import {formatBigDecimal} from "../../src/format.js"; + +describe("format", () => { + describe("formatBigDecimal", () => { + const testCases: [bigint, bigint, bigint, string][] = [ + [BigInt("103797739275696858"), BigInt("1000000000000000000"), BigInt("100000"), "0.10379"], + [BigInt("103797739275696858"), BigInt("1000000000000000000"), BigInt("1000"), "0.103"], + [BigInt("10379773927569685"), BigInt("1000000000000000000"), BigInt("1000"), "0.010"], + [BigInt("1037977392756968"), BigInt("1000000000000000000"), BigInt("1000"), "0.001"], + [BigInt("1037977392756968"), BigInt("1000000000000000000"), BigInt("100000"), "0.00103"], + [BigInt("58200000000000000"), BigInt("1000000000000000000"), BigInt("100000"), "0.05820"], + [BigInt("111103797739275696858"), BigInt("1000000000000000000"), BigInt("100000"), "111.10379"], + [BigInt("111103797739275696858"), BigInt("1000000000000000000"), BigInt("1000"), "111.103"], + [BigInt("1037977392756"), BigInt("1000000000000000000"), BigInt("100000"), "0.00000"], + ]; + for (const [numerator, denominator, decimalFactor, expectedString] of testCases) { + it(`format ${numerator} / ${denominator} correctly to ${expectedString}`, () => { + expect(formatBigDecimal(numerator, denominator, decimalFactor)).toBe(expectedString); + }); + } + }); +}); diff --git a/packages/utils/test/unit/promise.test.ts b/packages/utils/test/unit/promise.test.ts new file mode 100644 index 000000000000..c76e72f70a22 --- /dev/null +++ b/packages/utils/test/unit/promise.test.ts @@ -0,0 +1,73 @@ +/* Causing this error on usage of expect.any(Number) */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import {describe, it, expect} from "vitest"; +import {wrapPromise, PromiseRejectedResult, PromiseFulfilledResult} from "../../src/promise.js"; + +describe("promise", () => { + describe("wrapPromise", () => { + const timeoutMs = 100; + // TODO: Debug how promise is resolved quicker than the timeout + const promiseDurationMin = timeoutMs - 1; + // Add some margin for execution + const promiseDurationMax = timeoutMs + 20; + + it("should have initial status to pending", async () => { + const result = wrapPromise(Promise.resolve("my value")); + expect(result.status).toBe("pending"); + }); + + it("should resolve to value for a resolved promise", async () => { + const promise = Promise.resolve("my value"); + const result = wrapPromise(promise); + + await expect(promise).resolves.toBe("my value"); + expect(result).toEqual({ + value: "my value", + status: "fulfilled", + promise, + durationMs: expect.any(Number), + }); + }); + + it("should throw error for rejected promise", async () => { + const promise = Promise.reject("test error"); + const result = wrapPromise(promise); + + await expect(promise).rejects.toThrow("test error"); + await expect(result.promise).rejects.toThrow("test error"); + expect(result).toEqual({ + reason: "test error", + status: "rejected", + promise, + durationMs: expect.any(Number), + }); + }); + + it("should have correct durationMs attribute for promise which is resolved", async () => { + const promise = new Promise((resolve) => { + setTimeout(() => { + resolve("Resolved Value"); + }, timeoutMs); + }); + const result = wrapPromise(promise); + + await expect(promise).resolves.toBe("Resolved Value"); + expect((result as PromiseFulfilledResult).durationMs).toBeGreaterThanOrEqual(promiseDurationMin); + expect((result as PromiseFulfilledResult).durationMs).toBeLessThanOrEqual(promiseDurationMax); + }); + + it("should have correct durationMs attribute for promise which is rejected", async () => { + const promise = new Promise((_, reject) => { + setTimeout(() => { + reject("Rejected Error"); + }, timeoutMs); + }); + const result = wrapPromise(promise); + + await expect(promise).rejects.toThrow("Rejected Error"); + await expect(result.promise).rejects.toThrow("Rejected Error"); + expect((result as PromiseRejectedResult).durationMs).toBeGreaterThanOrEqual(promiseDurationMin); + expect((result as PromiseRejectedResult).durationMs).toBeLessThanOrEqual(promiseDurationMax); + }); + }); +}); diff --git a/packages/utils/test/unit/promiserace.test.ts b/packages/utils/test/unit/promiserace.test.ts index 5d0567553522..1f31a55014a4 100644 --- a/packages/utils/test/unit/promiserace.test.ts +++ b/packages/utils/test/unit/promiserace.test.ts @@ -1,7 +1,8 @@ import {describe, it, expect} from "vitest"; -import {racePromisesWithCutoff, RaceEvent} from "../../src/promise.js"; +import {resolveOrRacePromises, PromiseResult} from "../../src/promise.js"; +import {NonEmptyArray} from "../../src/types.js"; -describe("racePromisesWithCutoff", () => { +describe("resolveOrRacePromises", () => { const cutoffMs = 1000; const timeoutMs = 1500; @@ -9,96 +10,73 @@ describe("racePromisesWithCutoff", () => { new Promise((resolve) => { setTimeout(() => resolve(value), delay); }); + const rejectAfter = (value: string, delay: number): Promise => new Promise((_resolve, reject) => { setTimeout(() => reject(Error(value)), delay); }); - // For brevity in testcases - const precutoff = RaceEvent.precutoff; - const cutoff = RaceEvent.cutoff; - const resolvedatcutoff = RaceEvent.resolvedatcutoff; - const pretimeout = RaceEvent.pretimeout; - const timeout = RaceEvent.timeout; - const resolved = RaceEvent.resolved; - const rejected = RaceEvent.rejected; - - // Second item in testcase row i.e. array of numbers represent delay at which promise to be resolved - // or rejected (-ve number) - // Third item in testcase row is the expected value or error message in string - // Last item is expected events - const testcases: [string, number[], (string | Error)[], RaceEvent[]][] = [ - ["all resolve pre-cutoff", [100, 200], ["100", "200"], [resolved, resolved, precutoff]], - ["all resolve/reject pre-cutoff", [100, -200], ["100", "-200"], [resolved, rejected, precutoff]], - ["all reject pre-cutoff", [-100, -200], ["-100", "-200"], [rejected, rejected, precutoff]], - ["all reject pre-timeout", [-1100, -1200], ["-1100", "-1200"], [cutoff, rejected, rejected, pretimeout]], - ["race and resolve pre-timeout", [1100, 1200], ["1100", "pending"], [cutoff, resolved, pretimeout]], - [ - "race and resolve/reject pre-timeout", - [-1100, 1200, 1300], - ["-1100", "1200", "pending"], - [cutoff, rejected, resolved, pretimeout], - ], + const testCases: [string, number[], (string | Error)[]][] = [ + ["all resolve pre-cutoff", [100, 200], ["100", "200"]], + ["all resolve/reject pre-cutoff", [100, -200], ["100", "-200"]], + ["all reject pre-cutoff", [-100, -200], ["-100", "-200"]], + ["all reject pre-timeout", [-1100, -1200], ["-1100", "-1200"]], + ["race and resolve pre-timeout", [1100, 1200], ["1100", "pending"]], + ["race and resolve/reject pre-timeout", [-1100, 1200, 1300], ["-1100", "1200", "pending"]], [ "some resolve pre-cutoff with no race post cutoff", [100, -200, -1100, 1200], ["100", "-200", "pending", "pending"], - [resolved, rejected, resolvedatcutoff], ], [ "some reject pre-cutoff, with race resolution pre-timeout", [-100, -200, -1100, 1100, 1200], ["-100", "-200", "-1100", "1100", "pending"], - [rejected, rejected, cutoff, rejected, resolved, pretimeout], - ], - [ - "some reject pre-cutoff, rest reject pre-timeout", - [-100, -200, -1100, -1200], - ["-100", "-200", "-1100", "-1200"], - [rejected, rejected, cutoff, rejected, rejected, pretimeout], ], + ["some reject pre-cutoff, rest reject pre-timeout", [-100, -200, -1100, -1200], ["-100", "-200", "-1100", "-1200"]], [ "some resolve/reject pre-cutoff, some resolve/reject pre-timeout but no race beyond cutoff", [100, -200, -1100, 1100, 1700, -1700], ["100", "-200", "pending", "pending", "pending", "pending"], - [resolved, rejected, resolvedatcutoff], ], [ "none resolve/reject pre-cutoff with race resolution pre timeout", [-1100, 1200, 1700], ["-1100", "1200", "pending"], - [cutoff, rejected, resolved, pretimeout], - ], - [ - "none resolve pre-cutoff with race resolution pre timeout", - [1100, 1200, 1700], - ["1100", "pending", "pending"], - [cutoff, resolved, pretimeout], ], + ["none resolve pre-cutoff with race resolution pre timeout", [1100, 1200, 1700], ["1100", "pending", "pending"]], [ "some reject pre-cutoff, some reject pre-timeout, but no resolution till timeout", [-100, -1100, -1200, 1700, -1800], ["-100", "-1100", "-1200", "pending", "pending"], - [rejected, cutoff, rejected, rejected, timeout], ], - ["none resolve/reject pre timeout", [1600, -1700], ["pending", "pending"], [cutoff, timeout]], + ["none resolve/reject pre timeout", [1600, -1700], ["pending", "pending"]], ]; - for (const [name, promises, results, events] of testcases) { + for (const [name, timeouts, results] of testCases) { it(name, async () => { - const testPromises = promises.map((timeMs) => { + const testPromises = timeouts.map((timeMs) => { if (timeMs > 0) { return resolveAfter(`${timeMs}`, timeMs); } else { return rejectAfter(`${timeMs}`, -timeMs); } }); - const testEvents: RaceEvent[] = []; - const testResults = await racePromisesWithCutoff(testPromises, cutoffMs, timeoutMs, (event, _delayMs) => - testEvents.push(event) - ); - const testResultsCmp = testResults.map((res: string | Error) => (res instanceof Error ? res.message : res)); - expect({results: testResultsCmp, events: testEvents}).toEqual({results, events}); + const testResults = (await resolveOrRacePromises(testPromises as unknown as NonEmptyArray>, { + resolveTimeoutMs: cutoffMs, + raceTimeoutMs: timeoutMs, + })) as PromiseResult[]; + const testResultsCmp = testResults.map((r) => { + switch (r.status) { + case "fulfilled": + return r.value; + case "rejected": + return r.reason.message; + default: + return "pending"; + } + }); + expect(testResultsCmp).toEqual(results); }); } }); diff --git a/packages/validator/src/services/block.ts b/packages/validator/src/services/block.ts index dd7cea13c293..984550791384 100644 --- a/packages/validator/src/services/block.ts +++ b/packages/validator/src/services/block.ts @@ -11,12 +11,11 @@ import { } from "@lodestar/types"; import {ChainForkConfig} from "@lodestar/config"; import {ForkPreBlobs, ForkBlobs, ForkSeq, ForkExecution} from "@lodestar/params"; -import {ETH_TO_WEI, extendError, prettyBytes} from "@lodestar/utils"; +import {ETH_TO_WEI, extendError, formatBigDecimal, prettyBytes} from "@lodestar/utils"; import {Api, ApiError, routes} from "@lodestar/api"; import {IClock, LoggerVc} from "../util/index.js"; import {PubkeyHex} from "../types.js"; import {Metrics} from "../metrics.js"; -import {formatBigDecimal} from "../util/format.js"; import {ValidatorStore} from "./validatorStore.js"; import {BlockDutiesService, GENESIS_SLOT} from "./blockDuties.js"; diff --git a/packages/validator/src/util/format.ts b/packages/validator/src/util/format.ts index 6f4b61cf6826..a405383232c9 100644 --- a/packages/validator/src/util/format.ts +++ b/packages/validator/src/util/format.ts @@ -1,12 +1,3 @@ export function isValidatePubkeyHex(pubkeyHex: string): boolean { return /^0x[0-9a-fA-F]{96}$/.test(pubkeyHex); } - -export function formatBigDecimal(numerator: bigint, denominator: bigint, maxDecimalFactor: bigint): string { - const full = numerator / denominator; - const fraction = ((numerator - full * denominator) * maxDecimalFactor) / denominator; - - // zeros to be added post decimal are number of zeros in maxDecimalFactor - number of digits in fraction - const zerosPostDecimal = String(maxDecimalFactor).length - 1 - String(fraction).length; - return `${full}.${"0".repeat(zerosPostDecimal)}${fraction}`; -} diff --git a/packages/validator/test/unit/utils/format.test.ts b/packages/validator/test/unit/utils/format.test.ts deleted file mode 100644 index ab75c8fa1b72..000000000000 --- a/packages/validator/test/unit/utils/format.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {describe, it, expect} from "vitest"; -import {formatBigDecimal} from "../../../src/util/format.js"; - -describe("util / formatBigDecimal", function () { - const testCases: [bigint, bigint, bigint, string][] = [ - [BigInt("103797739275696858"), BigInt("1000000000000000000"), BigInt("100000"), "0.10379"], - [BigInt("103797739275696858"), BigInt("1000000000000000000"), BigInt("1000"), "0.103"], - [BigInt("10379773927569685"), BigInt("1000000000000000000"), BigInt("1000"), "0.010"], - [BigInt("1037977392756968"), BigInt("1000000000000000000"), BigInt("1000"), "0.001"], - [BigInt("1037977392756968"), BigInt("1000000000000000000"), BigInt("100000"), "0.00103"], - [BigInt("58200000000000000"), BigInt("1000000000000000000"), BigInt("100000"), "0.05820"], - [BigInt("111103797739275696858"), BigInt("1000000000000000000"), BigInt("100000"), "111.10379"], - [BigInt("111103797739275696858"), BigInt("1000000000000000000"), BigInt("1000"), "111.103"], - [BigInt("1037977392756"), BigInt("1000000000000000000"), BigInt("100000"), "0.00000"], - ]; - for (const [numerator, denominator, decimalFactor, expectedString] of testCases) { - it(`format ${numerator} / ${denominator} correctly to ${expectedString}`, () => { - expect(formatBigDecimal(numerator, denominator, decimalFactor)).toBe(expectedString); - }); - } -}); From b511d8394fe3ef5f609b45906245754390e7fcb8 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Mon, 5 Feb 2024 17:21:03 +0100 Subject: [PATCH 28/41] feat: allow to execute lodestar script inside docker container (#6392) --- lodestar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lodestar b/lodestar index 0b20ba4c9bcd..7cf5301e4de4 100755 --- a/lodestar +++ b/lodestar @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # Convenience script to run the lodestar binary from built source # From 7995c97f46944446ff81caeb1db766ec165e6008 Mon Sep 17 00:00:00 2001 From: Phil Ngo <58080811+philknows@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:39:49 -0500 Subject: [PATCH 29/41] chore: update funding.yml link (#6385) Update funding.yml link --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 709ceff687ac..989f4bc9c0b5 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -custom: https://gitcoin.co/grants/6034/lodestar-typescript-eth-consensus-client-by-chains +custom: https://etherscan.io/address/0xb4da52336092db22fe8e036866d59c6488604f89 From c4bf38576e0cba5880697de3a5ca4956162ede5e Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 6 Feb 2024 09:37:14 +0100 Subject: [PATCH 30/41] chore: fix failing sim tests (#6389) * Disable /ipfs/id/push/1.0.0 * Fix the peer disconnect errors * Align genesis time for logging * Fix genesis state issue * Increase timeotu for keystore unit test * Remove unintended protocol * Fix the test timeout * Update stopChildProcess * Update the @chainsafe/libp2p-identify * Compute effective genesis delay * Update workflow file to make it consistent * Increase the genesis delay calculation --- .github/workflows/test-sim.yml | 20 +++++++-- packages/beacon-node/package.json | 1 + .../beacon-node/src/network/libp2p/index.ts | 3 +- .../cli/test/sim/backup_eth_provider.test.ts | 1 + packages/cli/test/sim/deneb.test.ts | 5 ++- packages/cli/test/sim/endpoints.test.ts | 1 + packages/cli/test/sim/mixed_client.test.ts | 1 + packages/cli/test/sim/multi_fork.test.ts | 1 + .../keymanager/keystoreCache.test.ts | 5 ++- .../cli/test/utils/simulation/utils/index.ts | 30 ++++++++++++- .../simulation/validator_clients/index.ts | 4 +- .../validator_clients/lighthouse.ts | 1 - .../simulation/validator_clients/lodestar.ts | 2 +- packages/test-utils/src/childProcess.ts | 26 +++++++++++- yarn.lock | 42 +++++++++++++++++++ 15 files changed, 127 insertions(+), 16 deletions(-) diff --git a/.github/workflows/test-sim.yml b/.github/workflows/test-sim.yml index 65260fc38937..a90152d4ee3b 100644 --- a/.github/workflows/test-sim.yml +++ b/.github/workflows/test-sim.yml @@ -58,6 +58,12 @@ jobs: if: steps.cache-deps.outputs.cache-hit == 'true' # + - name: Download required docker images before running tests + run: | + docker pull ${{env.GETH_DOCKER_IMAGE}} + docker pull ${{env.LIGHTHOUSE_DOCKER_IMAGE}} + docker pull ${{env.NETHERMIND_DOCKER_IMAGE}} + - name: Sim tests multifork run: DEBUG='${{github.event.inputs.debug}}' yarn test:sim:multifork working-directory: packages/cli @@ -65,20 +71,28 @@ jobs: GENESIS_DELAY_SLOTS: ${{github.event.inputs.genesisDelaySlots}} - name: Sim tests endpoints - run: yarn test:sim:endpoints + run: DEBUG='${{github.event.inputs.debug}}' yarn test:sim:endpoints working-directory: packages/cli + env: + GENESIS_DELAY_SLOTS: ${{github.event.inputs.genesisDelaySlots}} - name: Sim tests deneb - run: yarn test:sim:deneb + run: DEBUG='${{github.event.inputs.debug}}' yarn test:sim:deneb working-directory: packages/cli + env: + GENESIS_DELAY_SLOTS: ${{github.event.inputs.genesisDelaySlots}} - name: Sim tests backup eth provider - run: yarn test:sim:backup_eth_provider + run: DEBUG='${{github.event.inputs.debug}}' yarn test:sim:backup_eth_provider working-directory: packages/cli + env: + GENESIS_DELAY_SLOTS: ${{github.event.inputs.genesisDelaySlots}} - name: Sim tests mixed client run: DEBUG='${{github.event.inputs.debug}}' yarn test:sim:mixedclient working-directory: packages/cli + env: + GENESIS_DELAY_SLOTS: ${{github.event.inputs.genesisDelaySlots}} - name: Upload debug log test files for "packages/cli" if: ${{ always() }} diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 90f2026e1873..f24963622d93 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -102,6 +102,7 @@ "@chainsafe/enr": "^3.0.0", "@chainsafe/libp2p-gossipsub": "^11.2.0", "@chainsafe/libp2p-noise": "^14.1.0", + "@chainsafe/libp2p-identify": "^1.0.0", "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/prometheus-gc-stats": "^1.0.0", "@chainsafe/ssz": "^0.14.0", diff --git a/packages/beacon-node/src/network/libp2p/index.ts b/packages/beacon-node/src/network/libp2p/index.ts index ccbd07355c32..8a8cca38c167 100644 --- a/packages/beacon-node/src/network/libp2p/index.ts +++ b/packages/beacon-node/src/network/libp2p/index.ts @@ -1,7 +1,8 @@ import {PeerId} from "@libp2p/interface"; import {Registry} from "prom-client"; import {ENR} from "@chainsafe/enr"; -import {identify} from "@libp2p/identify"; +// TODO: We should use this fork until https://github.com/libp2p/js-libp2p/pull/2387 +import {identify} from "@chainsafe/libp2p-identify"; import {bootstrap} from "@libp2p/bootstrap"; import {mdns} from "@libp2p/mdns"; import {createLibp2p} from "libp2p"; diff --git a/packages/cli/test/sim/backup_eth_provider.test.ts b/packages/cli/test/sim/backup_eth_provider.test.ts index 40ad7d4661de..5a38a27dc8f0 100644 --- a/packages/cli/test/sim/backup_eth_provider.test.ts +++ b/packages/cli/test/sim/backup_eth_provider.test.ts @@ -16,6 +16,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ ALTAIR_FORK_EPOCH: altairForkEpoch, BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, runTillEpoch: runTillEpoch + syncWaitEpoch, + initialNodes: 3, }); const env = await SimulationEnvironment.initWithDefaults( diff --git a/packages/cli/test/sim/deneb.test.ts b/packages/cli/test/sim/deneb.test.ts index 5ed84d3d2792..b66252b06892 100644 --- a/packages/cli/test/sim/deneb.test.ts +++ b/packages/cli/test/sim/deneb.test.ts @@ -18,12 +18,13 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ ALTAIR_FORK_EPOCH: altairForkEpoch, BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, runTillEpoch: runTillEpoch + syncWaitEpoch, + initialNodes: 2, }); const env = await SimulationEnvironment.initWithDefaults( { - id: "multi-fork", - logsDir: path.join(logFilesDir, "multi-fork"), + id: "deneb", + logsDir: path.join(logFilesDir, "deneb"), forkConfig, }, [ diff --git a/packages/cli/test/sim/endpoints.test.ts b/packages/cli/test/sim/endpoints.test.ts index ea55b70e26c1..a31b561e0578 100644 --- a/packages/cli/test/sim/endpoints.test.ts +++ b/packages/cli/test/sim/endpoints.test.ts @@ -16,6 +16,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ ALTAIR_FORK_EPOCH: altairForkEpoch, BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, runTillEpoch: 2, + initialNodes: 1, }); const env = await SimulationEnvironment.initWithDefaults( diff --git a/packages/cli/test/sim/mixed_client.test.ts b/packages/cli/test/sim/mixed_client.test.ts index ad2095f8c378..80c20471ede5 100644 --- a/packages/cli/test/sim/mixed_client.test.ts +++ b/packages/cli/test/sim/mixed_client.test.ts @@ -17,6 +17,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, CAPELLA_FORK_EPOCH: capellaForkEpoch, runTillEpoch: runTillEpoch + syncWaitEpoch, + initialNodes: 2, }); const env = await SimulationEnvironment.initWithDefaults( diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 24f42498c638..70f119609454 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -27,6 +27,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, CAPELLA_FORK_EPOCH: capellaForkEpoch, runTillEpoch: runTillEpoch + syncWaitEpoch, + initialNodes: 5, }); const env = await SimulationEnvironment.initWithDefaults( diff --git a/packages/cli/test/unit/cmds/validator/keymanager/keystoreCache.test.ts b/packages/cli/test/unit/cmds/validator/keymanager/keystoreCache.test.ts index ee0fedf301b6..40964a0a7b7d 100644 --- a/packages/cli/test/unit/cmds/validator/keymanager/keystoreCache.test.ts +++ b/packages/cli/test/unit/cmds/validator/keymanager/keystoreCache.test.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import {randomBytes} from "node:crypto"; -import {describe, it, expect, beforeEach} from "vitest"; +import {describe, it, expect, beforeEach, vi} from "vitest"; import tmp from "tmp"; import {Keystore} from "@chainsafe/bls-keystore"; import bls from "@chainsafe/bls"; @@ -12,6 +12,7 @@ import {LocalKeystoreDefinition} from "../../../../../src/cmds/validator/keymana const numberOfSigners = 10; describe("keystoreCache", () => { + vi.setConfig({testTimeout: 10000, hookTimeout: 50000}); let definitions: LocalKeystoreDefinition[]; let signers: SignerLocal[]; let secretKeys: Uint8Array[]; @@ -50,7 +51,7 @@ describe("keystoreCache", () => { passwords.push(password); secretKeys.push(secretKey.toBytes()); } - }, 50000); + }); describe("writeKeystoreCache", () => { it("should write a valid keystore cache file", async () => { diff --git a/packages/cli/test/utils/simulation/utils/index.ts b/packages/cli/test/utils/simulation/utils/index.ts index dfa66bed6580..bc0a4ee98d6f 100644 --- a/packages/cli/test/utils/simulation/utils/index.ts +++ b/packages/cli/test/utils/simulation/utils/index.ts @@ -17,18 +17,44 @@ export const avg = (arr: number[]): number => { return arr.length === 0 ? 0 : arr.reduce((p, c) => p + c, 0) / arr.length; }; +function getGenesisDelaySlots(initialNodes?: number): number { + if (process.env.GENESIS_DELAY_SLOTS) { + const genesisDelaySlots = parseInt(process.env.GENESIS_DELAY_SLOTS); + // If custom job is invoked and want to use default genesis delay then provider -1 as value + if (genesisDelaySlots >= 0) return genesisDelaySlots; + } + + if (initialNodes == null) return 40; + // Considering each node consists of EN, BN, VC and KM + // EN - Execution Node - 15s + const execution = 15; + // BN - Beacon Node - 15s + const beacon = 15; + // VC - Validator Client - 10s + const validator = 10; + // KM - Key Manager - 3s + const keyManager = 3; + // Initial script launch time - 10s + const initialLaunchScript = 10; + + return Math.ceil( + ((execution + beacon + validator + keyManager) * initialNodes + initialLaunchScript) / SIM_TESTS_SECONDS_PER_SLOT + ); +} + export function defineSimTestConfig( opts: Partial & { cliqueSealingPeriod?: number; additionalSlotsForTTD?: number; runTillEpoch: number; + // Used to calculate genesis delay + initialNodes?: number; } ): { estimatedTimeoutMs: number; forkConfig: ChainForkConfig; } { - const genesisDelaySeconds = - (process.env.GENESIS_DELAY_SLOTS ? parseInt(process.env.GENESIS_DELAY_SLOTS) : 40) * SIM_TESTS_SECONDS_PER_SLOT; + const genesisDelaySeconds = getGenesisDelaySlots(opts.initialNodes) * SIM_TESTS_SECONDS_PER_SLOT; const estimatedTimeoutMs = getEstimatedTimeInSecForRun({ diff --git a/packages/cli/test/utils/simulation/validator_clients/index.ts b/packages/cli/test/utils/simulation/validator_clients/index.ts index 1334382407e8..a75cbf6b1660 100644 --- a/packages/cli/test/utils/simulation/validator_clients/index.ts +++ b/packages/cli/test/utils/simulation/validator_clients/index.ts @@ -14,14 +14,14 @@ export async function createValidatorNode( "id" | "paths" | "forkConfig" | "nodeIndex" | "genesisTime" | "runner" | "beaconUrls" > ): Promise { - const {runner, forkConfig} = options; + const {runner} = options; const clId = `${options.id}-${client}`; const opts: ValidatorGeneratorOptions = { ...options, id: clId, keys: options.keys ?? {type: "no-keys"}, - genesisTime: options.genesisTime + forkConfig.GENESIS_DELAY, + genesisTime: options.genesisTime, clientOptions: options.clientOptions ?? {}, address: "127.0.0.1", }; diff --git a/packages/cli/test/utils/simulation/validator_clients/lighthouse.ts b/packages/cli/test/utils/simulation/validator_clients/lighthouse.ts index 27b2f485588d..a663fd0026c6 100644 --- a/packages/cli/test/utils/simulation/validator_clients/lighthouse.ts +++ b/packages/cli/test/utils/simulation/validator_clients/lighthouse.ts @@ -39,7 +39,6 @@ export const generateLighthouseValidatorNode: ValidatorNodeGenerator { + const pid = childProcess.pid; + + await new Promise((resolve, reject) => { childProcess.once("error", reject); - childProcess.once("close", resolve); + // We use `exit` instead of `close` as multiple processes can share same `stdio` + childProcess.once("exit", resolve); childProcess.kill(signal); }); + + if (pid != null && isPidRunning(pid)) { + // Wait for sometime and try to kill this time + await sleep(500); + await stopChildProcess(childProcess, "SIGKILL"); + } }; /** diff --git a/yarn.lock b/yarn.lock index 839c0dce5e90..0780e0bc2ef8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -385,6 +385,23 @@ 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@^14.1.0": version "14.1.0" resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-noise/-/libp2p-noise-14.1.0.tgz#4084a448cec73a941fddfc94751f6ce2e23c07cd" @@ -1629,6 +1646,21 @@ uint8arraylist "^2.4.3" uint8arrays "^5.0.0" +"@libp2p/peer-record@^7.0.7": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/peer-record/-/peer-record-7.0.7.tgz#e55145b2509592696f42ff73c38f813efbbbc688" + integrity sha512-RsggFJVAWQBA2z+ZJsK5nKHDKLmSd89IhFiE5GyImedQFiMkJz/gDFROzfNF2NdOyEBNdRy5SmC9scNFRQQD9A== + dependencies: + "@libp2p/crypto" "^4.0.1" + "@libp2p/interface" "^1.1.2" + "@libp2p/peer-id" "^4.0.5" + "@libp2p/utils" "^5.2.3" + "@multiformats/multiaddr" "^12.1.10" + protons-runtime "^5.0.0" + uint8-varint "^2.0.2" + uint8arraylist "^2.4.7" + uint8arrays "^5.0.0" + "@libp2p/peer-store@^10.0.5": version "10.0.5" resolved "https://registry.yarnpkg.com/@libp2p/peer-store/-/peer-store-10.0.5.tgz#b969d1707f5dcbf4d110e099270de285b075aa02" @@ -8054,6 +8086,16 @@ it-protobuf-stream@^1.0.2: protons-runtime "^5.0.0" uint8arraylist "^2.4.1" +it-protobuf-stream@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/it-protobuf-stream/-/it-protobuf-stream-1.1.2.tgz#4444d78fcae0fce949b4cbea622bf1d92667e64f" + integrity sha512-epZBuG+7cPaTxCR/Lf3ApshBdA9qfflGPQLfLLrp9VQ0w67Z2xo4H+SLLetav57/29oPtAXwVaoyemg99JOWzA== + dependencies: + it-length-prefixed-stream "^1.0.0" + it-stream-types "^2.0.1" + protons-runtime "^5.0.0" + uint8arraylist "^2.4.1" + it-pushable@^3.0.0, it-pushable@^3.1.2, it-pushable@^3.2.0, it-pushable@^3.2.1, it-pushable@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/it-pushable/-/it-pushable-3.2.3.tgz#e2b80aed90cfbcd54b620c0a0785e546d4e5f334" From d8b500add9ac830dcf671341616e19586a752dd8 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 6 Feb 2024 15:18:33 +0100 Subject: [PATCH 31/41] chore: upgrade geth and nethermind for sim tests (#6395) Upgrade Geth and Nethermind --- .github/workflows/test-sim.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-sim.yml b/.github/workflows/test-sim.yml index a90152d4ee3b..20eee3d11e77 100644 --- a/.github/workflows/test-sim.yml +++ b/.github/workflows/test-sim.yml @@ -23,9 +23,9 @@ on: default: 40 env: - GETH_DOCKER_IMAGE: ethereum/client-go:v1.11.6 + GETH_DOCKER_IMAGE: ethereum/client-go:v1.13.11 LIGHTHOUSE_DOCKER_IMAGE: sigp/lighthouse:latest-amd64-modern-dev - NETHERMIND_DOCKER_IMAGE: nethermind/nethermind:1.18.0 + NETHERMIND_DOCKER_IMAGE: nethermind/nethermind:1.25.3 jobs: tests-sim: From cb754f61164fdf9399d027de6b1ba12b33f24e7e Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 6 Feb 2024 15:24:19 +0100 Subject: [PATCH 32/41] fix: increase e2e env startup timeout (#6396) Increase e2e timeout --- scripts/run_e2e_env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_e2e_env.sh b/scripts/run_e2e_env.sh index 08f1680b30c6..e22b44ae6c00 100755 --- a/scripts/run_e2e_env.sh +++ b/scripts/run_e2e_env.sh @@ -6,7 +6,7 @@ function start_app() { nohup node --loader ts-node/esm packages/cli/test/scripts/e2e_test_env.ts > test-logs/e2e-test-env/simulation.out 2>&1 & echo $! > test-logs/e2e-test-env/simulation.pid echo "Wait for the node to be ready" - npx wait-port -t 60000 0.0.0.0:5001 + npx wait-port -t 120000 0.0.0.0:5001 } function stop_app() { From 274871de3f990b2f2fbf0dbfc768ce057e9efd4b Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 6 Feb 2024 17:02:15 +0100 Subject: [PATCH 33/41] chore: improve the sim tests logs (#6394) * Improve the sim tests logs * Update packages/utils/src/format.ts --------- Co-authored-by: Nico Flaig --- .../cli/test/sim/backup_eth_provider.test.ts | 3 ++ packages/cli/test/sim/multi_fork.test.ts | 3 ++ .../utils/simulation/SimulationEnvironment.ts | 30 ++++++++++++++----- .../cli/test/utils/simulation/interfaces.ts | 14 ++++----- packages/test-utils/src/childProcess.ts | 18 ++++++----- packages/utils/src/format.ts | 8 +++++ 6 files changed, 55 insertions(+), 21 deletions(-) diff --git a/packages/cli/test/sim/backup_eth_provider.test.ts b/packages/cli/test/sim/backup_eth_provider.test.ts index 5a38a27dc8f0..52ad83a4f5f8 100644 --- a/packages/cli/test/sim/backup_eth_provider.test.ts +++ b/packages/cli/test/sim/backup_eth_provider.test.ts @@ -79,4 +79,7 @@ await waitForSlot(env.clock.getLastSlotOfEpoch(bellatrixForkEpoch) + activePrese env, }); +await node2.beacon.job.stop(); +await node3.beacon.job.stop(); + await env.stop(); diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 70f119609454..e15f8b01fe90 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -259,4 +259,7 @@ await waitForHead(env, unknownBlockSync, { slot: headForUnknownBlockSync.response.data.message.slot, }); +await unknownBlockSync.beacon.job.stop(); +await unknownBlockSync.execution.job.stop(); + await env.stop(); diff --git a/packages/cli/test/utils/simulation/SimulationEnvironment.ts b/packages/cli/test/utils/simulation/SimulationEnvironment.ts index 5baec1b79048..3acd217e225e 100644 --- a/packages/cli/test/utils/simulation/SimulationEnvironment.ts +++ b/packages/cli/test/utils/simulation/SimulationEnvironment.ts @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import {EventEmitter} from "node:events"; import fs from "node:fs"; import {mkdir, writeFile} from "node:fs/promises"; import path from "node:path"; @@ -9,6 +8,7 @@ import {nodeUtils} from "@lodestar/beacon-node"; import {ChainForkConfig} from "@lodestar/config"; import {activePreset} from "@lodestar/params"; import {BeaconStateAllForks, interopSecretKey} from "@lodestar/state-transition"; +import {prettyMsToTime} from "@lodestar/utils"; import {EpochClock, MS_IN_SEC} from "./EpochClock.js"; import {ExternalSignerServer} from "./ExternalSignerServer.js"; import {SimulationTracker} from "./SimulationTracker.js"; @@ -42,7 +42,6 @@ export class SimulationEnvironment { readonly nodes: NodePair[] = []; readonly clock: EpochClock; readonly tracker: SimulationTracker; - readonly emitter: EventEmitter; readonly runner: IRunner; readonly externalSigner: ExternalSignerServer; @@ -52,6 +51,7 @@ export class SimulationEnvironment { private keysCount = 0; private nodePairCount = 0; private genesisState?: BeaconStateAllForks; + private runTimeout?: NodeJS.Timeout; private constructor(forkConfig: ChainForkConfig, options: SimulationOptions) { this.forkConfig = forkConfig; @@ -64,7 +64,6 @@ export class SimulationEnvironment { signal: this.options.controller.signal, }); - this.emitter = new EventEmitter(); this.externalSigner = new ExternalSignerServer([]); this.runner = new Runner({logsDir: this.options.logsDir}); this.tracker = SimulationTracker.initWithDefaultAssertions({ @@ -96,8 +95,14 @@ export class SimulationEnvironment { async start(opts: StartOpts): Promise { const currentTime = Date.now(); + console.log( + `Starting simulation environment "${this.options.id}". currentTime=${new Date( + currentTime + ).toISOString()} simulationTimeout=${prettyMsToTime(opts.runTimeoutMs)}` + ); + if (opts.runTimeoutMs > 0) { - setTimeout(() => { + this.runTimeout = setTimeout(() => { const slots = this.clock.getSlotFor((currentTime + opts.runTimeoutMs) / MS_IN_SEC); const epoch = this.clock.getEpochForSlot(slots); const slot = this.clock.getSlotIndexInEpoch(slots); @@ -116,7 +121,7 @@ export class SimulationEnvironment { this.stop( 1, - `Start sequence not completed before genesis, in ${msToGenesis}ms (approx. ${epoch}/${slot}).` + `Start sequence not completed before genesis, in ${prettyMsToTime(msToGenesis)} (approx. ${epoch}/${slot}).` ).catch((e) => console.error("Error on stop", e)); }, msToGenesis); @@ -126,21 +131,27 @@ export class SimulationEnvironment { await mkdir(this.options.rootDir); } + console.log("Starting the simulation runner"); await this.runner.start(); + + console.log("Starting execution nodes"); await Promise.all(this.nodes.map((node) => node.execution.job.start())); + console.log("Initializing genesis state for beacon nodes"); await this.initGenesisState(); if (!this.genesisState) { throw new Error("The genesis state for CL clients is not defined."); } + console.log("Starting beacon nodes"); await Promise.all(this.nodes.map((node) => node.beacon.job.start())); + + console.log("Starting validators"); await Promise.all(this.nodes.map((node) => node.validator?.job.start())); if (this.nodes.some((node) => node.validator?.keys.type === "remote")) { - console.log("Starting external signer..."); + console.log("Starting external signer"); await this.externalSigner.start(); - console.log("Started external signer"); for (const node of this.nodes) { if (node.validator?.keys.type === "remote") { @@ -156,6 +167,7 @@ export class SimulationEnvironment { } } + console.log("Starting the simulation tracker"); await this.tracker.start(); await Promise.all(this.nodes.map((node) => this.tracker.track(node))); } catch (error) { @@ -179,6 +191,10 @@ export class SimulationEnvironment { await this.runner.stop(); this.options.controller.abort(); + if (this.runTimeout) { + clearTimeout(this.runTimeout); + } + if (this.tracker.getErrorCount() > 0) { this.tracker.reporter.summary(); process.exit(this.tracker.getErrorCount() > 0 ? 1 : code); diff --git a/packages/cli/test/utils/simulation/interfaces.ts b/packages/cli/test/utils/simulation/interfaces.ts index 41339b58a1e0..62b02ea25708 100644 --- a/packages/cli/test/utils/simulation/interfaces.ts +++ b/packages/cli/test/utils/simulation/interfaces.ts @@ -29,19 +29,19 @@ export type SimulationOptions = { }; export enum BeaconClient { - Lodestar = "beacon_lodestar", - Lighthouse = "beacon_lighthouse", + Lodestar = "beacon-lodestar", + Lighthouse = "beacon-lighthouse", } export enum ValidatorClient { - Lodestar = "validator_lodestar", - Lighthouse = "validator_lighthouse", + Lodestar = "validator-lodestar", + Lighthouse = "validator-lighthouse", } export enum ExecutionClient { - Mock = "execution_mock", - Geth = "execution_geth", - Nethermind = "execution_nethermind", + Mock = "execution-mock", + Geth = "execution-geth", + Nethermind = "execution-nethermind", } export enum ExecutionStartMode { diff --git a/packages/test-utils/src/childProcess.ts b/packages/test-utils/src/childProcess.ts index c3cacb9a1509..ae01d7ce0e86 100644 --- a/packages/test-utils/src/childProcess.ts +++ b/packages/test-utils/src/childProcess.ts @@ -3,7 +3,7 @@ import childProcess from "node:child_process"; import stream from "node:stream"; import fs from "node:fs"; import path from "node:path"; -import {sleep} from "@lodestar/utils"; +import {prettyMsToTime, sleep} from "@lodestar/utils"; import {TestContext} from "./interfaces.js"; /** @@ -328,13 +328,15 @@ export async function spawnChildProcess( const timeSinceHealthCheckStart = Date.now() - startHealthCheckMs; if (timeSinceHealthCheckStart > logHealthChecksAfterMs) { console.log( - `Health check unsuccessful. logPrefix=${logPrefix} pid=${proc.pid} timeSinceHealthCheckStart=${timeSinceHealthCheckStart}` + `Health check unsuccessful. logPrefix=${logPrefix} pid=${ + proc.pid + } timeSinceHealthCheckStart=${prettyMsToTime(timeSinceHealthCheckStart)}` ); } } }) .catch((e) => { - console.error("error on health check, health functions must never throw", e); + console.error("Error on health check, health functions must never throw", e); }); }, healthCheckIntervalMs); @@ -344,7 +346,9 @@ export async function spawnChildProcess( if (intervalId !== undefined) { reject( new Error( - `Health check timeout. logPrefix=${logPrefix} pid=${proc.pid} healthTimeoutMs=${healthTimeoutMs}` + `Health check timeout. logPrefix=${logPrefix} pid=${proc.pid} healthTimeout=${prettyMsToTime( + healthTimeoutMs ?? 0 + )}` ) ); } @@ -358,9 +362,9 @@ export async function spawnChildProcess( reject( new Error( - `process exited before healthy. logPrefix=${logPrefix} pid=${ - proc.pid - } healthTimeoutMs=${healthTimeoutMs} code=${code} command="${command} ${args.join(" ")}"` + `Process exited before healthy. logPrefix=${logPrefix} pid=${proc.pid} healthTimeout=${prettyMsToTime( + healthTimeoutMs ?? 0 + )} code=${code} command="${command} ${args.join(" ")}"` ) ); }); diff --git a/packages/utils/src/format.ts b/packages/utils/src/format.ts index cf2352a4fbaa..0e89748af8f8 100644 --- a/packages/utils/src/format.ts +++ b/packages/utils/src/format.ts @@ -54,3 +54,11 @@ export function prettyWeiToEth(wei: bigint, suffix = false): string { if (suffix) eth += " ETH"; return eth; } + +/** + * Format milliseconds to time format HH:MM:SS.ms + */ +export function prettyMsToTime(timeMs: number): string { + const date = new Date(0, 0, 0, 0, 0, 0, timeMs); + return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}.${date.getMilliseconds()}`; +} From 2a8342d819a46b0807c1fa56998f20bf31b9076f Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 6 Feb 2024 20:39:33 +0100 Subject: [PATCH 34/41] test: flaky unit tests (#6398) * Fix clock flaky tests * Fix api server flaky tests * Auto assign port for testing server * Update fake timer --- .../beacon/genericServerTest/config.test.ts | 4 +- .../beacon/genericServerTest/debug.test.ts | 28 ++++++++----- .../beacon/genericServerTest/events.test.ts | 23 ++++++++--- packages/api/test/utils/genericServerTest.ts | 40 +++++++++++++------ packages/api/test/utils/utils.ts | 20 +++------- packages/validator/src/util/clock.ts | 2 +- .../validator/test/unit/utils/clock.test.ts | 2 +- 7 files changed, 73 insertions(+), 46 deletions(-) diff --git a/packages/api/test/unit/beacon/genericServerTest/config.test.ts b/packages/api/test/unit/beacon/genericServerTest/config.test.ts index e11e4cbff6cb..3e9c001bffbf 100644 --- a/packages/api/test/unit/beacon/genericServerTest/config.test.ts +++ b/packages/api/test/unit/beacon/genericServerTest/config.test.ts @@ -9,9 +9,7 @@ import {testData} from "../testData/config.js"; /* eslint-disable @typescript-eslint/naming-convention */ describe("beacon / config", () => { - describe("Run generic server test", () => { - runGenericServerTest(config, getClient, getRoutes, testData); - }); + runGenericServerTest(config, getClient, getRoutes, testData); it("Serialize Partial Spec object", () => { const returnTypes = getReturnTypes(); diff --git a/packages/api/test/unit/beacon/genericServerTest/debug.test.ts b/packages/api/test/unit/beacon/genericServerTest/debug.test.ts index 6f7889677ec6..9a4c4bd71ef1 100644 --- a/packages/api/test/unit/beacon/genericServerTest/debug.test.ts +++ b/packages/api/test/unit/beacon/genericServerTest/debug.test.ts @@ -1,5 +1,6 @@ -import {describe, it, expect, MockInstance} from "vitest"; +import {describe, it, expect, MockInstance, beforeAll, afterAll} from "vitest"; import {toHexString} from "@chainsafe/ssz"; +import {FastifyInstance} from "fastify"; import {ssz} from "@lodestar/types"; import {config} from "@lodestar/config/default"; import {Api, ReqTypes, routesData} from "../../../../src/beacon/routes/debug.js"; @@ -13,19 +14,28 @@ import {testData} from "../testData/debug.js"; describe( "beacon / debug", - function () { - describe("Run generic server test", () => { - runGenericServerTest(config, getClient, getRoutes, testData); - }); + () => { + runGenericServerTest(config, getClient, getRoutes, testData); // Get state by SSZ describe("getState() in SSZ format", () => { - const {baseUrl, server} = getTestServer(); const mockApi = getMockApi(routesData); - for (const route of Object.values(getRoutes(config, mockApi))) { - registerRoute(server, route); - } + let baseUrl: string; + let server: FastifyInstance; + + beforeAll(async () => { + const res = getTestServer(); + server = res.server; + for (const route of Object.values(getRoutes(config, mockApi))) { + registerRoute(server, route); + } + baseUrl = await res.start(); + }); + + afterAll(async () => { + if (server !== undefined) await server.close(); + }); for (const method of ["getState" as const, "getStateV2" as const]) { it(method, async () => { diff --git a/packages/api/test/unit/beacon/genericServerTest/events.test.ts b/packages/api/test/unit/beacon/genericServerTest/events.test.ts index 3e1c02396710..2d6c9462c1fd 100644 --- a/packages/api/test/unit/beacon/genericServerTest/events.test.ts +++ b/packages/api/test/unit/beacon/genericServerTest/events.test.ts @@ -1,4 +1,5 @@ -import {describe, it, expect, beforeEach, afterEach} from "vitest"; +import {describe, it, expect, beforeEach, afterEach, beforeAll, afterAll} from "vitest"; +import {FastifyInstance} from "fastify"; import {sleep} from "@lodestar/utils"; import {Api, routesData, EventType, BeaconEvent} from "../../../../src/beacon/routes/events.js"; import {getClient} from "../../../../src/beacon/client/events.js"; @@ -8,11 +9,23 @@ import {getMockApi, getTestServer} from "../../../utils/utils.js"; import {eventTestData} from "../testData/events.js"; describe("beacon / events", () => { - const {baseUrl, server} = getTestServer(); const mockApi = getMockApi(routesData); - for (const route of Object.values(getRoutes(mockApi))) { - registerRoute(server, route); - } + let server: FastifyInstance; + let baseUrl: string; + + beforeAll(async () => { + const res = getTestServer(); + server = res.server; + for (const route of Object.values(getRoutes(mockApi))) { + registerRoute(server, route); + } + + baseUrl = await res.start(); + }); + + afterAll(async () => { + if (server !== undefined) await server.close(); + }); let controller: AbortController; beforeEach(() => { diff --git a/packages/api/test/utils/genericServerTest.ts b/packages/api/test/utils/genericServerTest.ts index f0f805b7469a..4cd0263aaea8 100644 --- a/packages/api/test/utils/genericServerTest.ts +++ b/packages/api/test/utils/genericServerTest.ts @@ -1,4 +1,5 @@ -import {it, expect, MockInstance} from "vitest"; +import {it, expect, MockInstance, describe, beforeAll, afterAll} from "vitest"; +import {FastifyInstance} from "fastify"; import {ChainForkConfig} from "@lodestar/config"; import {ReqGeneric, Resolves} from "../../src/utils/index.js"; import {FetchOpts, HttpClient, IHttpClient} from "../../src/utils/client/index.js"; @@ -28,26 +29,39 @@ export function runGenericServerTest< testCases: GenericServerTestCases ): void { const mockApi = getMockApi(testCases); - const {baseUrl, server} = getTestServer(); + let server: FastifyInstance; - const httpClient = new HttpClientSpy({baseUrl}); - const client = getClient(config, httpClient); + let client: Api; + let httpClient: HttpClientSpy; - for (const route of Object.values(getRoutes(config, mockApi))) { - registerRoute(server, route); - } + beforeAll(async () => { + const res = getTestServer(); + server = res.server; + + for (const route of Object.values(getRoutes(config, mockApi))) { + registerRoute(server, route); + } + + const baseUrl = await res.start(); + httpClient = new HttpClientSpy({baseUrl}); + client = getClient(config, httpClient); + }); - for (const key of Object.keys(testCases)) { - const routeId = key as keyof Api; - const testCase = testCases[routeId]; + afterAll(async () => { + if (server !== undefined) await server.close(); + }); + + describe("run generic server tests", () => { + it.each(Object.keys(testCases))("%s", async (key) => { + const routeId = key as keyof Api; + const testCase = testCases[routeId]; - it(routeId as string, async () => { // Register mock data for this route // TODO: Look for the type error (mockApi[routeId] as MockInstance).mockResolvedValue(testCases[routeId].res); // Do the call - const res = await (client[routeId] as APIClientHandler)(...(testCase.args as any[])); + const res = await client[routeId](...(testCase.args as any[])); // Use spy to assert argument serialization if (testCase.query) { @@ -64,7 +78,7 @@ export function runGenericServerTest< // Assert returned value is correct expect(res.response).toEqual(testCase.res); }); - } + }); } class HttpClientSpy extends HttpClient { diff --git a/packages/api/test/utils/utils.ts b/packages/api/test/utils/utils.ts index cca89c8e4fd5..b19899016117 100644 --- a/packages/api/test/utils/utils.ts +++ b/packages/api/test/utils/utils.ts @@ -1,13 +1,10 @@ -import {beforeAll, afterAll, MockedObject, vi} from "vitest"; +import {MockedObject, vi} from "vitest"; import qs from "qs"; import fastify, {FastifyInstance} from "fastify"; import {mapValues} from "@lodestar/utils"; import {ServerApi} from "../../src/interfaces.js"; -export function getTestServer(): {baseUrl: string; server: FastifyInstance} { - const port = Math.floor(Math.random() * (65535 - 49152)) + 49152; - const baseUrl = `http://localhost:${port}`; - +export function getTestServer(): {server: FastifyInstance; start: () => Promise} { const server = fastify({ ajv: {customOptions: {coerceTypes: "array"}}, querystringParser: (str) => qs.parse(str, {comma: true, parseArrays: false}), @@ -19,9 +16,9 @@ export function getTestServer(): {baseUrl: string; server: FastifyInstance} { done(); }); - beforeAll(async () => { - await new Promise((resolve, reject) => { - server.listen({port}, function (err, address) { + const start = (): Promise => + new Promise((resolve, reject) => { + server.listen({port: 0}, function (err, address) { if (err !== null && err != undefined) { reject(err); } else { @@ -29,13 +26,8 @@ export function getTestServer(): {baseUrl: string; server: FastifyInstance} { } }); }); - }); - - afterAll(async () => { - await server.close(); - }); - return {baseUrl, server}; + return {start, server}; } export function getMockApi>( diff --git a/packages/validator/src/util/clock.ts b/packages/validator/src/util/clock.ts index ca29eacd41c2..837fb82809bd 100644 --- a/packages/validator/src/util/clock.ts +++ b/packages/validator/src/util/clock.ts @@ -138,7 +138,7 @@ export class Clock implements IClock { */ export function getCurrentSlotAround(config: ChainForkConfig, genesisTime: TimeSeconds): Slot { const diffInSeconds = Date.now() / 1000 - genesisTime; - const slotsSinceGenesis = Math.round(diffInSeconds / config.SECONDS_PER_SLOT); + const slotsSinceGenesis = Math.floor(diffInSeconds / config.SECONDS_PER_SLOT); return GENESIS_SLOT + slotsSinceGenesis; } diff --git a/packages/validator/test/unit/utils/clock.test.ts b/packages/validator/test/unit/utils/clock.test.ts index 15f95ddbe2ee..dfa9d386e663 100644 --- a/packages/validator/test/unit/utils/clock.test.ts +++ b/packages/validator/test/unit/utils/clock.test.ts @@ -11,7 +11,7 @@ describe("util / Clock", function () { beforeEach(() => { controller = new AbortController(); - vi.useFakeTimers(); + vi.useFakeTimers({now: Date.now()}); }); afterEach(() => { From 3adf2c2eb233483b5bea2abf253a7cce68c36af9 Mon Sep 17 00:00:00 2001 From: Cayman Date: Tue, 6 Feb 2024 16:32:17 -0500 Subject: [PATCH 35/41] chore: bump gossipsub (#6399) --- packages/beacon-node/package.json | 2 +- yarn.lock | 19 +++++-------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index f24963622d93..60955b4c2259 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -100,7 +100,7 @@ "@chainsafe/blst": "^0.2.9", "@chainsafe/discv5": "^9.0.0", "@chainsafe/enr": "^3.0.0", - "@chainsafe/libp2p-gossipsub": "^11.2.0", + "@chainsafe/libp2p-gossipsub": "^11.2.1", "@chainsafe/libp2p-noise": "^14.1.0", "@chainsafe/libp2p-identify": "^1.0.0", "@chainsafe/persistent-merkle-tree": "^0.6.1", diff --git a/yarn.lock b/yarn.lock index 0780e0bc2ef8..e4059083f9e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -364,10 +364,10 @@ resolved "https://registry.yarnpkg.com/@chainsafe/is-ip/-/is-ip-2.0.2.tgz#7311e7403f11d8c5cfa48111f56fcecaac37c9f6" integrity sha512-ndGqEMG1W5WkGagaqOZHpPU172AGdxr+LD15sv3WIUvT5oCFUrG1Y0CW/v2Egwj4JXEvSibaIIIqImsm98y1nA== -"@chainsafe/libp2p-gossipsub@^11.2.0": - version "11.2.0" - resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-gossipsub/-/libp2p-gossipsub-11.2.0.tgz#4134dc68d9e3e0c327474b48fbd6e1f76f97550b" - integrity sha512-VymXl4Z4qEIUxH4FjgbcVqyuapVHhzrJxADO4t84QOOWv9f8uQYV+c0cgwjneOW3XyTYBOHaZqyTHTngTrKjtQ== +"@chainsafe/libp2p-gossipsub@^11.2.1": + version "11.2.1" + resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-gossipsub/-/libp2p-gossipsub-11.2.1.tgz#80a993cca657084c861b78513ee0ff516bfb96f9" + integrity sha512-2NvlOY4Jfwn7U/sKF0kILl3+luHxq9hhEiBqZRqLTIV8LYmMQl9VpTMgMvRwKzgn/NDeZzsPb8olk2o00tkmZw== dependencies: "@libp2p/crypto" "^4.0.1" "@libp2p/interface" "^1.1.2" @@ -375,7 +375,6 @@ "@libp2p/peer-id" "^4.0.5" "@libp2p/pubsub" "^9.0.8" "@multiformats/multiaddr" "^12.1.14" - abortable-iterator "^5.0.1" denque "^2.1.0" it-length-prefixed "^9.0.4" it-pipe "^3.0.1" @@ -3533,14 +3532,6 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -abortable-iterator@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/abortable-iterator/-/abortable-iterator-5.0.1.tgz#5d93eba6fa8287a973a9ea090c64ca08b3777780" - integrity sha512-hlZ5Z8UwqrKsJcelVPEqDduZowJPBQJ9ZhBC2FXpja3lXy8X6MoI5uMzIgmrA8+3jcVnp8TF/tx+IBBqYJNUrg== - dependencies: - get-iterator "^2.0.0" - it-stream-types "^2.0.1" - abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" @@ -6805,7 +6796,7 @@ get-iterator@^1.0.2: resolved "https://registry.npmjs.org/get-iterator/-/get-iterator-1.0.2.tgz" integrity sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg== -get-iterator@^2.0.0, get-iterator@^2.0.1: +get-iterator@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-2.0.1.tgz#a904829f61bace789e0d64bd1a504c511a015c3f" integrity sha512-7HuY/hebu4gryTDT7O/XY/fvY9wRByEGdK6QOa4of8npTcv0+NS6frFKABcf6S9EBAsveTuKTsZQQBFMMNILIg== From b6890adf2882b02960b8ffc5d685f3576dc6d0cc Mon Sep 17 00:00:00 2001 From: Julien Date: Tue, 6 Feb 2024 13:56:25 -0800 Subject: [PATCH 36/41] feat: add ERC-55 support to ExecutionAddress (#6355) * feat: add ERC-55 support to ExecutionAddress * chore: address PR comments * chore: address PR comments * fix: cleanup * fix: lower case * chore: address PR comments --- packages/types/package.json | 3 +- packages/types/src/bellatrix/sszTypes.ts | 2 +- packages/types/src/index.ts | 2 +- packages/types/src/primitive/sszTypes.ts | 3 +- packages/types/src/utils/executionAddress.ts | 48 +++++++++++++ .../utils/{StringType.ts => stringType.ts} | 0 .../types/test/unit/executionAddress.test.ts | 72 +++++++++++++++++++ 7 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 packages/types/src/utils/executionAddress.ts rename packages/types/src/utils/{StringType.ts => stringType.ts} (100%) create mode 100644 packages/types/test/unit/executionAddress.test.ts diff --git a/packages/types/package.json b/packages/types/package.json index e75266d9ed01..51baccc89314 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -74,7 +74,8 @@ "types": "lib/index.d.ts", "dependencies": { "@chainsafe/ssz": "^0.14.0", - "@lodestar/params": "^1.15.0" + "@lodestar/params": "^1.15.0", + "ethereum-cryptography": "^2.0.0" }, "keywords": [ "ethereum", diff --git a/packages/types/src/bellatrix/sszTypes.ts b/packages/types/src/bellatrix/sszTypes.ts index c6919d04b631..08f0378ef92a 100644 --- a/packages/types/src/bellatrix/sszTypes.ts +++ b/packages/types/src/bellatrix/sszTypes.ts @@ -9,7 +9,7 @@ import { import {ssz as primitiveSsz} from "../primitive/index.js"; import {ssz as phase0Ssz} from "../phase0/index.js"; import {ssz as altairSsz} from "../altair/index.js"; -import {stringType} from "../utils/StringType.js"; +import {stringType} from "../utils/stringType.js"; const { Bytes32, diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index d90b55909884..6931271aaa29 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -3,6 +3,6 @@ export * as ssz from "./sszTypes.js"; // Typeguards export * from "./utils/typeguards.js"; // String type -export {StringType, stringType} from "./utils/StringType.js"; +export {StringType, stringType} from "./utils/stringType.js"; // Container utils export * from "./utils/container.js"; diff --git a/packages/types/src/primitive/sszTypes.ts b/packages/types/src/primitive/sszTypes.ts index 65c81d1247b9..068a32e2cc17 100644 --- a/packages/types/src/primitive/sszTypes.ts +++ b/packages/types/src/primitive/sszTypes.ts @@ -1,4 +1,5 @@ import {ByteVectorType, UintNumberType, UintBigintType, BooleanType} from "@chainsafe/ssz"; +import {ExecutionAddressType} from "../utils/executionAddress.js"; export const Boolean = new BooleanType(); export const Byte = new UintNumberType(1); @@ -61,4 +62,4 @@ export const BLSPubkey = Bytes48; export const BLSSignature = Bytes96; export const Domain = Bytes32; export const ParticipationFlags = new UintNumberType(1, {setBitwiseOR: true}); -export const ExecutionAddress = Bytes20; +export const ExecutionAddress = new ExecutionAddressType(); diff --git a/packages/types/src/utils/executionAddress.ts b/packages/types/src/utils/executionAddress.ts new file mode 100644 index 000000000000..9d555c016f04 --- /dev/null +++ b/packages/types/src/utils/executionAddress.ts @@ -0,0 +1,48 @@ +import {keccak256} from "ethereum-cryptography/keccak.js"; +import {ByteVectorType} from "@chainsafe/ssz"; + +export type ByteVector = Uint8Array; + +export class ExecutionAddressType extends ByteVectorType { + constructor() { + super(20, {typeName: "ExecutionAddress"}); + } + toJson(value: ByteVector): unknown { + const str = super.toJson(value) as string; + return toChecksumAddress(str); + } +} + +function isAddressValid(address: string): boolean { + return /^(0x)?[0-9a-f]{40}$/i.test(address); +} + +/** + * Formats an address according to [ERC55](https://eips.ethereum.org/EIPS/eip-55) + */ +export function toChecksumAddress(address: string): string { + if (!isAddressValid(address)) { + throw Error(`Invalid address: ${address}`); + } + + const rawAddress = (address.startsWith("0x") ? address.slice(2) : address).toLowerCase(); + const chars = rawAddress.split(""); + + // Inspired by https://github.com/ethers-io/ethers.js/blob/cac1da1f912c2ae9ba20f25aa51a91766673cd76/src.ts/address/address.ts#L8 + const expanded = new Uint8Array(chars.length); + for (let i = 0; i < expanded.length; i++) { + expanded[i] = rawAddress[i].charCodeAt(0); + } + + const hashed = keccak256(expanded); + for (let i = 0; i < chars.length; i += 2) { + if (hashed[i >> 1] >> 4 >= 8) { + chars[i] = chars[i].toUpperCase(); + } + if ((hashed[i >> 1] & 0x0f) >= 8) { + chars[i + 1] = chars[i + 1].toUpperCase(); + } + } + + return "0x" + chars.join(""); +} diff --git a/packages/types/src/utils/StringType.ts b/packages/types/src/utils/stringType.ts similarity index 100% rename from packages/types/src/utils/StringType.ts rename to packages/types/src/utils/stringType.ts diff --git a/packages/types/test/unit/executionAddress.test.ts b/packages/types/test/unit/executionAddress.test.ts new file mode 100644 index 000000000000..841cd52468f5 --- /dev/null +++ b/packages/types/test/unit/executionAddress.test.ts @@ -0,0 +1,72 @@ +import {describe, it, expect} from "vitest"; +import {toChecksumAddress} from "../../src/utils/executionAddress.js"; + +describe("toChecksumAddress", () => { + it("should fail with invalid addresses", () => { + expect(() => toChecksumAddress("1234")).toThrowError("Invalid address: 1234"); + expect(() => toChecksumAddress("0x1234")).toThrowError("Invalid address: 0x1234"); + }); + + it("should format addresses as ERC55", () => { + type TestCase = { + address: string; + checksumAddress: string; + }; + + const testCases: TestCase[] = [ + // Input all caps + { + address: "0x52908400098527886E0F7030069857D2E4169EE7", + checksumAddress: "0x52908400098527886E0F7030069857D2E4169EE7", + }, + { + address: "0xDE709F2102306220921060314715629080E2FB77", + checksumAddress: "0xde709f2102306220921060314715629080e2fb77", + }, + // Without 0x prefix + { + address: "52908400098527886e0f7030069857d2e4169ee7", + checksumAddress: "0x52908400098527886E0F7030069857D2E4169EE7", + }, + // All caps + { + address: "0x52908400098527886e0f7030069857d2e4169ee7", + checksumAddress: "0x52908400098527886E0F7030069857D2E4169EE7", + }, + { + address: "0x8617e340b3d01fa5f11f306f4090fd50e238070d", + checksumAddress: "0x8617E340B3D01FA5F11F306F4090FD50E238070D", + }, + // All lower + { + address: "0xde709f2102306220921060314715629080e2fb77", + checksumAddress: "0xde709f2102306220921060314715629080e2fb77", + }, + { + address: "0x27b1fdb04752bbc536007a920d24acb045561c26", + checksumAddress: "0x27b1fdb04752bbc536007a920d24acb045561c26", + }, + // Normal + { + address: "0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", + checksumAddress: "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", + }, + { + address: "0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", + checksumAddress: "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", + }, + { + address: "0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", + checksumAddress: "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", + }, + { + address: "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", + checksumAddress: "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", + }, + ]; + + for (const {address, checksumAddress} of testCases) { + expect(toChecksumAddress(address)).toBe(checksumAddress); + } + }); +}); From 924a6cd4957c75db1085e4551d744aba27afa7fb Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Wed, 7 Feb 2024 14:18:14 +0100 Subject: [PATCH 37/41] fix: parse --blindedLocal flag value as boolean (#6403) --- packages/cli/src/cmds/validator/options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index 20bfc106d258..a5b4044f6867 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -268,7 +268,7 @@ export const validatorOptions: CliCommandOptions = { }, blindedLocal: { - type: "string", + type: "boolean", description: "Request fetching local block in blinded format for produceBlockV3", defaultDescription: `${defaultOptions.blindedLocal}`, }, From 3bc9673addd709892c52452bbcb268225ee0db98 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Wed, 7 Feb 2024 14:26:07 +0100 Subject: [PATCH 38/41] fix: correct error message if produceBlockV3 request fails (#6405) --- packages/validator/src/services/block.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/validator/src/services/block.ts b/packages/validator/src/services/block.ts index 984550791384..a28f7c019d0b 100644 --- a/packages/validator/src/services/block.ts +++ b/packages/validator/src/services/block.ts @@ -212,7 +212,7 @@ export class BlockProposingService { blindedLocal, builderBoostFactor, }); - ApiError.assert(res, "Failed to produce block: validator.produceBlockV2"); + ApiError.assert(res, "Failed to produce block: validator.produceBlockV3"); const {response} = res; const debugLogCtx = { From 1857a49404f2ad965025333f0f6b3422d4c1943f Mon Sep 17 00:00:00 2001 From: Phil Ngo <58080811+philknows@users.noreply.github.com> Date: Wed, 7 Feb 2024 08:39:24 -0500 Subject: [PATCH 39/41] chore: v1.15.1 release (#6379) * v1.15.1 * fix: ignore stale keystore lockfiles (#6363) * fix: ignore stale keystore lockfiles * Update error message if lockfile is already acquired * Update keymanager lockfile e2e tests * fix: ignore forkchoice invalidations if latestValidHash not found (#6361) * fix: ignore forkchoice invalidations if latestValidHash not found * rename for better understanding * update the lvh search start index * apply feedback * fix: parse --blindedLocal flag value as boolean (#6403) --------- Co-authored-by: Nico Flaig Co-authored-by: g11tech --- lerna.json | 2 +- packages/api/package.json | 10 ++-- packages/beacon-node/package.json | 26 ++++----- .../blocks/verifyBlocksExecutionPayloads.ts | 4 +- packages/cli/package.json | 30 +++++------ packages/cli/src/cmds/validator/options.ts | 2 +- packages/cli/src/util/lockfile.ts | 54 +++++++++++-------- .../test/e2e/importKeystoresFromApi.test.ts | 8 +-- .../decryptKeystoreDefinitions.test.ts | 13 +++-- packages/config/package.json | 6 +-- packages/db/package.json | 8 +-- packages/db/src/controller/level.ts | 2 +- packages/flare/package.json | 14 ++--- packages/fork-choice/package.json | 12 ++--- .../fork-choice/src/protoArray/interface.ts | 2 +- .../fork-choice/src/protoArray/protoArray.ts | 45 ++++++++-------- .../protoArray/executionStatusUpdates.test.ts | 10 ++-- packages/light-client/package.json | 14 ++--- packages/logger/package.json | 6 +-- packages/params/package.json | 2 +- packages/prover/package.json | 18 +++---- packages/reqresp/package.json | 12 ++--- packages/spec-test-util/package.json | 4 +- packages/state-transition/package.json | 10 ++-- packages/test-utils/package.json | 6 +-- packages/types/package.json | 4 +- packages/utils/package.json | 2 +- packages/validator/package.json | 18 +++---- yarn.lock | 19 +++---- 29 files changed, 187 insertions(+), 176 deletions(-) diff --git a/lerna.json b/lerna.json index 2a9439d49715..5362d02551d8 100644 --- a/lerna.json +++ b/lerna.json @@ -4,7 +4,7 @@ ], "npmClient": "yarn", "useNx": true, - "version": "1.15.0", + "version": "1.15.1", "stream": true, "command": { "version": { diff --git a/packages/api/package.json b/packages/api/package.json index 533961953b9a..e9fa0936c3f8 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": { ".": { @@ -71,10 +71,10 @@ "dependencies": { "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/ssz": "^0.14.0", - "@lodestar/config": "^1.15.0", - "@lodestar/params": "^1.15.0", - "@lodestar/types": "^1.15.0", - "@lodestar/utils": "^1.15.0", + "@lodestar/config": "^1.15.1", + "@lodestar/params": "^1.15.1", + "@lodestar/types": "^1.15.1", + "@lodestar/utils": "^1.15.1", "eventsource": "^2.0.2", "qs": "^6.11.1" }, diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 8ce625fb0d54..e2366bb86051 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": { ".": { @@ -121,18 +121,18 @@ "@libp2p/peer-id-factory": "^4.0.3", "@libp2p/prometheus-metrics": "^3.0.10", "@libp2p/tcp": "9.0.10", - "@lodestar/api": "^1.15.0", - "@lodestar/config": "^1.15.0", - "@lodestar/db": "^1.15.0", - "@lodestar/fork-choice": "^1.15.0", - "@lodestar/light-client": "^1.15.0", - "@lodestar/logger": "^1.15.0", - "@lodestar/params": "^1.15.0", - "@lodestar/reqresp": "^1.15.0", - "@lodestar/state-transition": "^1.15.0", - "@lodestar/types": "^1.15.0", - "@lodestar/utils": "^1.15.0", - "@lodestar/validator": "^1.15.0", + "@lodestar/api": "^1.15.1", + "@lodestar/config": "^1.15.1", + "@lodestar/db": "^1.15.1", + "@lodestar/fork-choice": "^1.15.1", + "@lodestar/light-client": "^1.15.1", + "@lodestar/logger": "^1.15.1", + "@lodestar/params": "^1.15.1", + "@lodestar/reqresp": "^1.15.1", + "@lodestar/state-transition": "^1.15.1", + "@lodestar/types": "^1.15.1", + "@lodestar/utils": "^1.15.1", + "@lodestar/validator": "^1.15.1", "@multiformats/multiaddr": "^12.1.3", "@types/datastore-level": "^3.0.0", "buffer-xor": "^2.0.2", diff --git a/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts b/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts index 5dbe104c9541..91242d879f85 100644 --- a/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts +++ b/packages/beacon-node/src/chain/blocks/verifyBlocksExecutionPayloads.ts @@ -319,7 +319,7 @@ export async function verifyBlockExecutionPayload( const lvhResponse = { executionStatus, latestValidExecHash: execResult.latestValidHash, - invalidateFromBlockHash: toHexString(block.message.parentRoot), + invalidateFromParentBlockRoot: toHexString(block.message.parentRoot), }; const execError = new BlockError(block, { code: BlockErrorCode.EXECUTION_ENGINE_ERROR, @@ -416,7 +416,7 @@ function getSegmentErrorResponse( invalidSegmentLVH = { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: lvhResponse.latestValidExecHash, - invalidateFromBlockHash: parentBlock.blockRoot, + invalidateFromParentBlockRoot: parentBlock.blockRoot, }; } } diff --git a/packages/cli/package.json b/packages/cli/package.json index 616dce9d4f68..839d42c7b3d6 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@chainsafe/lodestar", - "version": "1.15.0", + "version": "1.15.1", "description": "Command line interface for lodestar", "author": "ChainSafe Systems", "license": "LGPL-3.0", @@ -66,19 +66,18 @@ "@libp2p/crypto": "^3.0.4", "@libp2p/peer-id": "^4.0.4", "@libp2p/peer-id-factory": "^4.0.3", - "@lodestar/api": "^1.15.0", - "@lodestar/beacon-node": "^1.15.0", - "@lodestar/config": "^1.15.0", - "@lodestar/db": "^1.15.0", - "@lodestar/light-client": "^1.15.0", - "@lodestar/logger": "^1.15.0", - "@lodestar/params": "^1.15.0", - "@lodestar/state-transition": "^1.15.0", - "@lodestar/types": "^1.15.0", - "@lodestar/utils": "^1.15.0", - "@lodestar/validator": "^1.15.0", + "@lodestar/api": "^1.15.1", + "@lodestar/beacon-node": "^1.15.1", + "@lodestar/config": "^1.15.1", + "@lodestar/db": "^1.15.1", + "@lodestar/light-client": "^1.15.1", + "@lodestar/logger": "^1.15.1", + "@lodestar/params": "^1.15.1", + "@lodestar/state-transition": "^1.15.1", + "@lodestar/types": "^1.15.1", + "@lodestar/utils": "^1.15.1", + "@lodestar/validator": "^1.15.1", "@multiformats/multiaddr": "^12.1.3", - "@types/lockfile": "^1.0.2", "bip39": "^3.1.0", "deepmerge": "^4.3.1", "ethers": "^6.7.0", @@ -87,9 +86,9 @@ "got": "^11.8.6", "inquirer": "^9.1.5", "js-yaml": "^4.1.0", - "lockfile": "^1.0.4", "lodash": "^4.17.21", "prom-client": "^15.1.0", + "proper-lockfile": "^4.1.2", "rimraf": "^4.4.1", "source-map-support": "^0.5.21", "uint8arrays": "^4.0.9", @@ -97,12 +96,13 @@ "yargs": "^17.7.1" }, "devDependencies": { - "@lodestar/test-utils": "^1.15.0", + "@lodestar/test-utils": "^1.15.1", "@types/debug": "^4.1.7", "@types/expand-tilde": "^2.0.0", "@types/got": "^9.6.12", "@types/inquirer": "^9.0.3", "@types/lodash": "^4.14.192", + "@types/proper-lockfile": "^4.1.4", "@types/yargs": "^17.0.24" } } diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index ecc8ad32ca87..6d8d40f2dfdb 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -267,7 +267,7 @@ export const validatorOptions: CliCommandOptions = { }, blindedLocal: { - type: "string", + type: "boolean", description: "Request fetching local block in blinded format for produceBlockV3", defaultDescription: `${defaultOptions.blindedLocal}`, }, diff --git a/packages/cli/src/util/lockfile.ts b/packages/cli/src/util/lockfile.ts index 65933e8f2897..f7a6ddf4d57d 100644 --- a/packages/cli/src/util/lockfile.ts +++ b/packages/cli/src/util/lockfile.ts @@ -1,29 +1,21 @@ -export type Lockfile = { - lockSync(path: string): void; - unlockSync(path: string): void; -}; - -const lockFile: Lockfile = (await import("lockfile")) as Lockfile; - -function getLockFilepath(filepath: string): string { - return `${filepath}.lock`; -} - -/** - * When lockfile is imported, it registers listeners to process - * Since it's only used by the validator client, require lazily to not pollute - * beacon_node client context - */ -function getLockFile(): Lockfile { - return lockFile; -} +import {lockSync, unlockSync} from "proper-lockfile"; /** * Creates a .lock file for `filepath`, argument passed must not be the lock path * @param filepath File to lock, i.e. `keystore_0001.json` */ export function lockFilepath(filepath: string): void { - getLockFile().lockSync(getLockFilepath(filepath)); + try { + lockSync(filepath, { + // Allows to lock files that do not exist + realpath: false, + }); + } catch (e) { + if (isLockfileError(e) && e.code === "ELOCKED") { + e.message = `${filepath} is already in use by another process`; + } + throw e; + } } /** @@ -31,7 +23,23 @@ export function lockFilepath(filepath: string): void { * @param filepath File to unlock, i.e. `keystore_0001.json` */ export function unlockFilepath(filepath: string): void { - // Does not throw if the lock file is already deleted - // https://github.com/npm/lockfile/blob/6590779867ee9bdc5dbebddc962640759892bb91/lockfile.js#L68 - getLockFile().unlockSync(getLockFilepath(filepath)); + try { + unlockSync(filepath, { + // Allows to unlock files that do not exist + realpath: false, + }); + } catch (e) { + if (isLockfileError(e) && e.code === "ENOTACQUIRED") { + // Do not throw if the lock file is already deleted + return; + } + throw e; + } +} + +// https://github.com/moxystudio/node-proper-lockfile/blob/9f8c303c91998e8404a911dc11c54029812bca69/lib/lockfile.js#L53 +export type LockfileError = Error & {code: "ELOCKED" | "ENOTACQUIRED"}; + +function isLockfileError(e: unknown): e is LockfileError { + return e instanceof Error && (e as LockfileError).code !== undefined; } diff --git a/packages/cli/test/e2e/importKeystoresFromApi.test.ts b/packages/cli/test/e2e/importKeystoresFromApi.test.ts index bb91d467b86a..1cf5f107e226 100644 --- a/packages/cli/test/e2e/importKeystoresFromApi.test.ts +++ b/packages/cli/test/e2e/importKeystoresFromApi.test.ts @@ -95,10 +95,10 @@ describe("import keystores from api", function () { validator.on("exit", (code) => { if (code !== null && code > 0) { // process should exit with code > 0, and an error related to locks. Sample error: - // vc 351591: ✖ Error: EEXIST: file already exists, open '/tmp/tmp-351554-dMctEAj7sJIz/import-keystores-test/keystores/0x8be678633e927aa0435addad5dcd5283fef6110d91362519cd6d43e61f6c017d724fa579cc4b2972134e050b6ba120c0/voting-keystore.json.lock' - // at Object.openSync (node:fs:585:3) - // at Module.exports.lockSync (/home/lion/Code/eth2.0/lodestar/node_modules/lockfile/lockfile.js:277:17) - if (/EEXIST.*voting-keystore\.json\.lock/.test(vcProc2Stderr.read())) { + // vc 351591: ✖ Error: /tmp/tmp-5080-lwNxdM5Ok9ya/import-keystores-test/keystores/0x8be678633e927aa0435addad5dcd5283fef6110d91362519cd6d43e61f6c017d724fa579cc4b2972134e050b6ba120c0/voting-keystore.json is already in use by another process + // at /home/runner/actions-runner/_work/lodestar/lodestar/node_modules/proper-lockfile/lib/lockfile.js:68:47 + // ... more stack trace + if (/Error.*voting-keystore\.json is already in use by another process/.test(vcProc2Stderr.read())) { resolve(); } else { reject(Error(`Second validator proc exited with unknown error. stderr:\n${vcProc2Stderr.read()}`)); diff --git a/packages/cli/test/unit/validator/decryptKeystoreDefinitions.test.ts b/packages/cli/test/unit/validator/decryptKeystoreDefinitions.test.ts index f24b83ae43a6..0f4173604405 100644 --- a/packages/cli/test/unit/validator/decryptKeystoreDefinitions.test.ts +++ b/packages/cli/test/unit/validator/decryptKeystoreDefinitions.test.ts @@ -7,6 +7,7 @@ import {cachedSeckeysHex} from "../../utils/cachedKeys.js"; import {testFilesDir} from "../../utils.js"; import {decryptKeystoreDefinitions} from "../../../src/cmds/validator/keymanager/decryptKeystoreDefinitions.js"; import {LocalKeystoreDefinition} from "../../../src/cmds/validator/keymanager/interface.js"; +import {LockfileError, unlockFilepath} from "../../../src/util/lockfile.js"; describe("decryptKeystoreDefinitions", () => { vi.setConfig({testTimeout: 100_000}); @@ -22,6 +23,10 @@ describe("decryptKeystoreDefinitions", () => { let definitions: LocalKeystoreDefinition[] = []; beforeEach(async () => { + // remove lockfiles from proper-lockfile cache + for (const {keystorePath} of definitions) { + unlockFilepath(keystorePath); + } rimraf.sync(dataDir); rimraf.sync(importFromDir); @@ -46,7 +51,9 @@ describe("decryptKeystoreDefinitions", () => { expect(fs.existsSync(cacheFilePath)).toBe(true); // remove lockfiles created during cache file preparation - rimraf.sync(path.join(importFromDir, "*.lock"), {glob: true}); + for (const {keystorePath} of definitions) { + unlockFilepath(keystorePath); + } }); testDecryptKeystoreDefinitions(cacheFilePath); @@ -75,14 +82,14 @@ describe("decryptKeystoreDefinitions", () => { await decryptKeystoreDefinitions(definitions, {logger: console, signal, cacheFilePath}); expect.fail("Second decrypt should fail due to failure to get lockfile"); } catch (e) { - expect((e as Error).message.startsWith("EEXIST: file already exists")).toBe(true); + expect((e as LockfileError).code).toBe("ELOCKED"); } }); it("decrypt keystores if lockfiles already exist if ignoreLockFile=true", async () => { await decryptKeystoreDefinitions(definitions, {logger: console, signal, cacheFilePath}); - // lockfiles should exist after the first run + await decryptKeystoreDefinitions(definitions, {logger: console, signal, cacheFilePath, ignoreLockFile: true}); }); } diff --git a/packages/config/package.json b/packages/config/package.json index a36da8c6240a..0f47077b7ea5 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/config", - "version": "1.15.0", + "version": "1.15.1", "description": "Chain configuration required for lodestar", "author": "ChainSafe Systems", "license": "Apache-2.0", @@ -65,7 +65,7 @@ ], "dependencies": { "@chainsafe/ssz": "^0.14.0", - "@lodestar/params": "^1.15.0", - "@lodestar/types": "^1.15.0" + "@lodestar/params": "^1.15.1", + "@lodestar/types": "^1.15.1" } } diff --git a/packages/db/package.json b/packages/db/package.json index f11e5b48995c..7de4789864a3 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/db", - "version": "1.15.0", + "version": "1.15.1", "description": "DB modules of Lodestar", "author": "ChainSafe Systems", "homepage": "https://github.com/ChainSafe/lodestar#readme", @@ -38,13 +38,13 @@ }, "dependencies": { "@chainsafe/ssz": "^0.14.0", - "@lodestar/config": "^1.15.0", - "@lodestar/utils": "^1.15.0", + "@lodestar/config": "^1.15.1", + "@lodestar/utils": "^1.15.1", "@types/levelup": "^4.3.3", "it-all": "^3.0.4", "level": "^8.0.0" }, "devDependencies": { - "@lodestar/logger": "^1.15.0" + "@lodestar/logger": "^1.15.1" } } diff --git a/packages/db/src/controller/level.ts b/packages/db/src/controller/level.ts index 3eed75958e3e..2cea8681c95b 100644 --- a/packages/db/src/controller/level.ts +++ b/packages/db/src/controller/level.ts @@ -52,7 +52,7 @@ export class LevelDbController implements DatabaseController latestValidHashIndex) { const invalidNode = this.invalidateNodeByIndex(invalidateIndex); invalidateIndex = invalidNode.parent; @@ -368,8 +369,8 @@ export class ProtoArray { }); } - private getNodeIndexFromLVH(latestValidExecHash: RootHex, ancestorOfIndex: number): number | null { - let nodeIndex = this.nodes[ancestorOfIndex].parent; + private getNodeIndexFromLVH(latestValidExecHash: RootHex, ancestorFromIndex: number): number | null { + let nodeIndex: number | undefined = ancestorFromIndex; while (nodeIndex !== undefined && nodeIndex >= 0) { const node = this.getNodeFromIndex(nodeIndex); if ( diff --git a/packages/fork-choice/test/unit/protoArray/executionStatusUpdates.test.ts b/packages/fork-choice/test/unit/protoArray/executionStatusUpdates.test.ts index 94e5cd3ac9a0..e6916f24800f 100644 --- a/packages/fork-choice/test/unit/protoArray/executionStatusUpdates.test.ts +++ b/packages/fork-choice/test/unit/protoArray/executionStatusUpdates.test.ts @@ -149,7 +149,7 @@ describe("executionStatus / normal updates", () => { { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "2C", - invalidateFromBlockHash: "3C", + invalidateFromParentBlockRoot: "3C", }, 3 ); @@ -212,7 +212,7 @@ describe("executionStatus / normal updates", () => { { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "1A", - invalidateFromBlockHash: "3A", + invalidateFromParentBlockRoot: "3A", }, 3 ); @@ -259,7 +259,7 @@ describe("executionStatus / invalidate all postmerge chain", () => { { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - invalidateFromBlockHash: "3B", + invalidateFromParentBlockRoot: "3B", }, 3 ); @@ -336,7 +336,7 @@ describe("executionStatus / poision forkchoice if we invalidate previous valid", { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - invalidateFromBlockHash: "3A", + invalidateFromParentBlockRoot: "3A", }, 3 ) @@ -373,7 +373,7 @@ describe("executionStatus / poision forkchoice if we validate previous invalid", { executionStatus: ExecutionStatus.Invalid, latestValidExecHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - invalidateFromBlockHash: "3B", + invalidateFromParentBlockRoot: "3B", }, 3 ); diff --git a/packages/light-client/package.json b/packages/light-client/package.json index 456600cbd0bc..73fad280129c 100644 --- a/packages/light-client/package.json +++ b/packages/light-client/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": { ".": { @@ -70,12 +70,12 @@ "@chainsafe/bls": "7.1.1", "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/ssz": "^0.14.0", - "@lodestar/api": "^1.15.0", - "@lodestar/config": "^1.15.0", - "@lodestar/params": "^1.15.0", - "@lodestar/state-transition": "^1.15.0", - "@lodestar/types": "^1.15.0", - "@lodestar/utils": "^1.15.0", + "@lodestar/api": "^1.15.1", + "@lodestar/config": "^1.15.1", + "@lodestar/params": "^1.15.1", + "@lodestar/state-transition": "^1.15.1", + "@lodestar/types": "^1.15.1", + "@lodestar/utils": "^1.15.1", "mitt": "^3.0.0", "strict-event-emitter-types": "^2.0.0" }, diff --git a/packages/logger/package.json b/packages/logger/package.json index f1a5ddad1a06..ea649cffb958 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": { ".": { @@ -66,14 +66,14 @@ }, "types": "lib/index.d.ts", "dependencies": { - "@lodestar/utils": "^1.15.0", + "@lodestar/utils": "^1.15.1", "winston": "^3.8.2", "winston-daily-rotate-file": "^4.7.1", "winston-transport": "^4.5.0" }, "devDependencies": { "@chainsafe/threads": "^1.11.1", - "@lodestar/test-utils": "^1.15.0", + "@lodestar/test-utils": "^1.15.1", "@types/triple-beam": "^1.3.2", "rimraf": "^4.4.1", "triple-beam": "^1.3.0" diff --git a/packages/params/package.json b/packages/params/package.json index d41dae06816e..d94090b3f6ea 100644 --- a/packages/params/package.json +++ b/packages/params/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/params", - "version": "1.15.0", + "version": "1.15.1", "description": "Chain parameters required for lodestar", "author": "ChainSafe Systems", "license": "Apache-2.0", diff --git a/packages/prover/package.json b/packages/prover/package.json index 600f4b4d4d75..7ca0090b58aa 100644 --- a/packages/prover/package.json +++ b/packages/prover/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": { ".": { @@ -72,13 +72,13 @@ "@ethereumjs/tx": "^4.1.2", "@ethereumjs/util": "^8.0.6", "@ethereumjs/vm": "^6.4.2", - "@lodestar/api": "^1.15.0", - "@lodestar/config": "^1.15.0", - "@lodestar/light-client": "^1.15.0", - "@lodestar/logger": "^1.15.0", - "@lodestar/params": "^1.15.0", - "@lodestar/types": "^1.15.0", - "@lodestar/utils": "^1.15.0", + "@lodestar/api": "^1.15.1", + "@lodestar/config": "^1.15.1", + "@lodestar/light-client": "^1.15.1", + "@lodestar/logger": "^1.15.1", + "@lodestar/params": "^1.15.1", + "@lodestar/types": "^1.15.1", + "@lodestar/utils": "^1.15.1", "ethereum-cryptography": "^1.2.0", "find-up": "^6.3.0", "http-proxy": "^1.18.1", @@ -87,7 +87,7 @@ "yargs": "^17.7.1" }, "devDependencies": { - "@lodestar/test-utils": "^1.15.0", + "@lodestar/test-utils": "^1.15.1", "@types/http-proxy": "^1.17.10", "@types/yargs": "^17.0.24", "axios": "^1.3.4", diff --git a/packages/reqresp/package.json b/packages/reqresp/package.json index 3856177449d3..66700cf317d0 100644 --- a/packages/reqresp/package.json +++ b/packages/reqresp/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": { ".": { @@ -56,9 +56,9 @@ "dependencies": { "@chainsafe/fast-crc32c": "^4.1.1", "@libp2p/interface": "^1.1.1", - "@lodestar/config": "^1.15.0", - "@lodestar/params": "^1.15.0", - "@lodestar/utils": "^1.15.0", + "@lodestar/config": "^1.15.1", + "@lodestar/params": "^1.15.1", + "@lodestar/utils": "^1.15.1", "it-all": "^3.0.4", "it-pipe": "^3.0.1", "snappy": "^7.2.2", @@ -67,8 +67,8 @@ "uint8arraylist": "^2.4.7" }, "devDependencies": { - "@lodestar/logger": "^1.15.0", - "@lodestar/types": "^1.15.0", + "@lodestar/logger": "^1.15.1", + "@lodestar/types": "^1.15.1", "libp2p": "1.1.1" }, "peerDependencies": { diff --git a/packages/spec-test-util/package.json b/packages/spec-test-util/package.json index f8d953e408fd..e94fc35c7111 100644 --- a/packages/spec-test-util/package.json +++ b/packages/spec-test-util/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/spec-test-util", - "version": "1.15.0", + "version": "1.15.1", "description": "Spec test suite generator from yaml test files", "author": "ChainSafe Systems", "license": "Apache-2.0", @@ -62,7 +62,7 @@ "blockchain" ], "dependencies": { - "@lodestar/utils": "^1.15.0", + "@lodestar/utils": "^1.15.1", "async-retry": "^1.3.3", "axios": "^1.3.4", "rimraf": "^4.4.1", diff --git a/packages/state-transition/package.json b/packages/state-transition/package.json index 8a1aea19f140..ed76e116fe82 100644 --- a/packages/state-transition/package.json +++ b/packages/state-transition/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": { ".": { @@ -63,10 +63,10 @@ "@chainsafe/persistent-merkle-tree": "^0.6.1", "@chainsafe/persistent-ts": "^0.19.1", "@chainsafe/ssz": "^0.14.0", - "@lodestar/config": "^1.15.0", - "@lodestar/params": "^1.15.0", - "@lodestar/types": "^1.15.0", - "@lodestar/utils": "^1.15.0", + "@lodestar/config": "^1.15.1", + "@lodestar/params": "^1.15.1", + "@lodestar/types": "^1.15.1", + "@lodestar/utils": "^1.15.1", "bigint-buffer": "^1.1.5", "buffer-xor": "^2.0.2" }, diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 038cd743bdd7..1d976c5e609e 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@lodestar/test-utils", "private": true, - "version": "1.15.0", + "version": "1.15.1", "description": "Test utilities reused across other packages", "author": "ChainSafe Systems", "license": "Apache-2.0", @@ -60,8 +60,8 @@ "dependencies": { "@chainsafe/bls": "7.1.1", "@chainsafe/bls-keystore": "^3.0.0", - "@lodestar/params": "^1.15.0", - "@lodestar/utils": "^1.15.0", + "@lodestar/params": "^1.15.1", + "@lodestar/utils": "^1.15.1", "axios": "^1.3.4", "testcontainers": "^10.2.1", "tmp": "^0.2.1", diff --git a/packages/types/package.json b/packages/types/package.json index 1e9b811becfa..3888eeae2cc2 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": { ".": { @@ -73,7 +73,7 @@ "types": "lib/index.d.ts", "dependencies": { "@chainsafe/ssz": "^0.14.0", - "@lodestar/params": "^1.15.0" + "@lodestar/params": "^1.15.1" }, "keywords": [ "ethereum", diff --git a/packages/utils/package.json b/packages/utils/package.json index fa1dd4fdd829..1a5497c94581 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -11,7 +11,7 @@ "bugs": { "url": "https://github.com/ChainSafe/lodestar/issues" }, - "version": "1.15.0", + "version": "1.15.1", "type": "module", "exports": "./lib/index.js", "files": [ diff --git a/packages/validator/package.json b/packages/validator/package.json index 020792107c3b..bbc64ede4de0 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -1,6 +1,6 @@ { "name": "@lodestar/validator", - "version": "1.15.0", + "version": "1.15.1", "description": "A Typescript implementation of the validator client", "author": "ChainSafe Systems", "license": "LGPL-3.0", @@ -49,18 +49,18 @@ "dependencies": { "@chainsafe/bls": "7.1.1", "@chainsafe/ssz": "^0.14.0", - "@lodestar/api": "^1.15.0", - "@lodestar/config": "^1.15.0", - "@lodestar/db": "^1.15.0", - "@lodestar/params": "^1.15.0", - "@lodestar/state-transition": "^1.15.0", - "@lodestar/types": "^1.15.0", - "@lodestar/utils": "^1.15.0", + "@lodestar/api": "^1.15.1", + "@lodestar/config": "^1.15.1", + "@lodestar/db": "^1.15.1", + "@lodestar/params": "^1.15.1", + "@lodestar/state-transition": "^1.15.1", + "@lodestar/types": "^1.15.1", + "@lodestar/utils": "^1.15.1", "bigint-buffer": "^1.1.5", "strict-event-emitter-types": "^2.0.0" }, "devDependencies": { - "@lodestar/test-utils": "^1.15.0", + "@lodestar/test-utils": "^1.15.1", "bigint-buffer": "^1.1.5", "rimraf": "^4.4.1" } diff --git a/yarn.lock b/yarn.lock index 27754c484466..ce67d0db390d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2955,11 +2955,6 @@ "@types/level-errors" "*" "@types/node" "*" -"@types/lockfile@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/lockfile/-/lockfile-1.0.2.tgz#3f77e84171a2b7e3198bd5717c7547a54393baf8" - integrity sha512-jD5VbvhfMhaYN4M3qPJuhMVUg3Dfc4tvPvLEAXn6GXbs/ajDFtCQahX37GIE65ipTI3I+hEvNaXS3MYAn9Ce3Q== - "@types/lodash@^4.14.192": version "4.14.192" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.192.tgz#5790406361a2852d332d41635d927f1600811285" @@ -3043,6 +3038,13 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== +"@types/proper-lockfile@^4.1.4": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@types/proper-lockfile/-/proper-lockfile-4.1.4.tgz#cd9fab92bdb04730c1ada542c356f03620f84008" + integrity sha512-uo2ABllncSqg9F1D4nugVl9v93RmjxF6LJzQLMLDdPaXCUIDPeOJ21Gbqi43xNKzBi/WQ0Q0dICqufzQbMjipQ== + dependencies: + "@types/retry" "*" + "@types/qs@^6.9.7": version "6.9.7" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" @@ -9045,13 +9047,6 @@ locate-path@^7.1.0: dependencies: p-locate "^6.0.0" -lockfile@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz" - integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== - dependencies: - signal-exit "^3.0.2" - lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" From d1caa1f61730551908ab2b969b972c7978909e87 Mon Sep 17 00:00:00 2001 From: Cayman Date: Wed, 7 Feb 2024 14:13:45 -0500 Subject: [PATCH 40/41] fix: fix regression in getCurrentSlotAround (#6407) --- packages/validator/src/util/clock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/validator/src/util/clock.ts b/packages/validator/src/util/clock.ts index 837fb82809bd..ca29eacd41c2 100644 --- a/packages/validator/src/util/clock.ts +++ b/packages/validator/src/util/clock.ts @@ -138,7 +138,7 @@ export class Clock implements IClock { */ export function getCurrentSlotAround(config: ChainForkConfig, genesisTime: TimeSeconds): Slot { const diffInSeconds = Date.now() / 1000 - genesisTime; - const slotsSinceGenesis = Math.floor(diffInSeconds / config.SECONDS_PER_SLOT); + const slotsSinceGenesis = Math.round(diffInSeconds / config.SECONDS_PER_SLOT); return GENESIS_SLOT + slotsSinceGenesis; } From cb99fc4041e08dfff407909d18e0b3c05ff8562c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:34:49 +0000 Subject: [PATCH 41/41] chore(deps): bump browserify-sign from 4.2.1 to 4.2.2 (#6071) Bumps [browserify-sign](https://github.com/crypto-browserify/browserify-sign) from 4.2.1 to 4.2.2. - [Changelog](https://github.com/browserify/browserify-sign/blob/main/CHANGELOG.md) - [Commits](https://github.com/crypto-browserify/browserify-sign/compare/v4.2.1...v4.2.2) --- updated-dependencies: - dependency-name: browserify-sign dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/yarn.lock b/yarn.lock index e4059083f9e9..427db4fdc496 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4206,7 +4206,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.1, bn.js@^4.11.9: resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.0.0, bn.js@^5.1.1: +bn.js@^5.0.0: version "5.2.0" resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== @@ -4308,7 +4308,7 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: +browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz" integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== @@ -4317,19 +4317,19 @@ browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.2.1" - resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz" - integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.2.tgz#e78d4b69816d6e3dd1c747e64e9947f9ad79bc7e" + integrity sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg== dependencies: - bn.js "^5.1.1" - browserify-rsa "^4.0.1" + bn.js "^5.2.1" + browserify-rsa "^4.1.0" create-hash "^1.2.0" create-hmac "^1.1.7" - elliptic "^6.5.3" + elliptic "^6.5.4" inherits "^2.0.4" - parse-asn1 "^5.1.5" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" + parse-asn1 "^5.1.6" + readable-stream "^3.6.2" + safe-buffer "^5.2.1" browserify-zlib@^0.2.0: version "0.2.0" @@ -5675,7 +5675,7 @@ electron@^26.2.2: "@types/node" "^18.11.18" extract-zip "^2.0.1" -elliptic@6.5.4, elliptic@^6.5.3: +elliptic@6.5.4, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -10226,7 +10226,7 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-asn1@^5.0.0, parse-asn1@^5.1.5: +parse-asn1@^5.0.0, parse-asn1@^5.1.6: version "5.1.6" resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz" integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== @@ -10895,6 +10895,15 @@ readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readable-stream@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.3.0.tgz#0914d0c72db03b316c9733bb3461d64a3cc50cba" @@ -11215,7 +11224,7 @@ safe-array-concat@^1.0.1: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==