diff --git a/packages/cli/test/scripts/e2e_test_env.ts b/packages/cli/test/scripts/e2e_test_env.ts index 8e564c577f6..24d0142827a 100644 --- a/packages/cli/test/scripts/e2e_test_env.ts +++ b/packages/cli/test/scripts/e2e_test_env.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; -import {BeaconClient, ExecutionClient} from "../utils/simulation/interfaces.js"; -import {SimulationEnvironment} from "../utils/simulation/simulationEnvironment.js"; -import {defineSimTestConfig, logFilesDir} from "../utils/simulation/utils/index.js"; -import {connectAllNodes} from "../utils/simulation/utils/network.js"; +import {BeaconClient, ExecutionClient} from "../utils/crucible/interfaces.js"; +import {Simulation} from "../utils/crucible/simulation.js"; +import {defineSimTestConfig, logFilesDir} from "../utils/crucible/utils/index.js"; +import {connectAllNodes} from "../utils/crucible/utils/network.js"; const altairForkEpoch = 1; const bellatrixForkEpoch = 2; @@ -17,7 +17,7 @@ const {forkConfig} = defineSimTestConfig({ initialNodes: 2, }); -const env = await SimulationEnvironment.initWithDefaults( +const env = await Simulation.initWithDefaults( { id: "e2e-test-env", logsDir: path.join(logFilesDir, "e2e-test-env"), diff --git a/packages/cli/test/sim/backupEthProvider.test.ts b/packages/cli/test/sim/backupEthProvider.test.ts index b44de0afa54..1310119c9c3 100644 --- a/packages/cli/test/sim/backupEthProvider.test.ts +++ b/packages/cli/test/sim/backupEthProvider.test.ts @@ -1,11 +1,11 @@ /* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; import {activePreset} from "@lodestar/params"; -import {SimulationEnvironment} from "../utils/simulation/simulationEnvironment.js"; -import {nodeAssertion} from "../utils/simulation/assertions/nodeAssertion.js"; -import {AssertionMatch, BeaconClient, ExecutionClient} from "../utils/simulation/interfaces.js"; -import {defineSimTestConfig, logFilesDir, replaceIpFromUrl} from "../utils/simulation/utils/index.js"; -import {connectAllNodes, waitForSlot} from "../utils/simulation/utils/network.js"; +import {Simulation} from "../utils/crucible/simulation.js"; +import {nodeAssertion} from "../utils/crucible/assertions/nodeAssertion.js"; +import {Match, BeaconClient, ExecutionClient} from "../utils/crucible/interfaces.js"; +import {defineSimTestConfig, logFilesDir, replaceIpFromUrl} from "../utils/crucible/utils/index.js"; +import {connectAllNodes, waitForSlot} from "../utils/crucible/utils/network.js"; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; @@ -19,7 +19,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ initialNodes: 3, }); -const env = await SimulationEnvironment.initWithDefaults( +const env = await Simulation.initWithDefaults( { id: "backup-eth-provider", logsDir: path.join(logFilesDir, "backup-eth-provider"), @@ -31,7 +31,7 @@ const env = await SimulationEnvironment.initWithDefaults( env.tracker.register({ ...nodeAssertion, match: ({slot}) => { - return slot === 1 ? AssertionMatch.Assert | AssertionMatch.Capture | AssertionMatch.Remove : AssertionMatch.None; + return slot === 1 ? Match.Assert | Match.Capture | Match.Remove : Match.None; }, }); diff --git a/packages/cli/test/sim/deneb.test.ts b/packages/cli/test/sim/deneb.test.ts index 2fc28761997..b9c30a5ff52 100644 --- a/packages/cli/test/sim/deneb.test.ts +++ b/packages/cli/test/sim/deneb.test.ts @@ -1,11 +1,11 @@ /* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; -import {SimulationEnvironment} from "../utils/simulation/simulationEnvironment.js"; -import {BeaconClient, ExecutionClient, ValidatorClient} from "../utils/simulation/interfaces.js"; -import {defineSimTestConfig, logFilesDir} from "../utils/simulation/utils/index.js"; -import {connectAllNodes, waitForSlot} from "../utils/simulation/utils/network.js"; -import {createBlobsAssertion} from "../utils/simulation/assertions/blobsAssertion.js"; -import {assertCheckpointSync, assertRangeSync} from "../utils/simulation/utils/syncing.js"; +import {Simulation} from "../utils/crucible/simulation.js"; +import {BeaconClient, ExecutionClient, ValidatorClient} from "../utils/crucible/interfaces.js"; +import {defineSimTestConfig, logFilesDir} from "../utils/crucible/utils/index.js"; +import {connectAllNodes, waitForSlot} from "../utils/crucible/utils/network.js"; +import {createBlobsAssertion} from "../utils/crucible/assertions/blobsAssertion.js"; +import {assertCheckpointSync, assertRangeSync} from "../utils/crucible/utils/syncing.js"; const runTillEpoch = 6; const syncWaitEpoch = 2; @@ -20,7 +20,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ additionalSlotsForTTD: 0, }); -const env = await SimulationEnvironment.initWithDefaults( +const env = await Simulation.initWithDefaults( { id: "deneb", logsDir: path.join(logFilesDir, "deneb"), diff --git a/packages/cli/test/sim/endpoints.test.ts b/packages/cli/test/sim/endpoints.test.ts index 9fd5371ca01..b58bece04d9 100644 --- a/packages/cli/test/sim/endpoints.test.ts +++ b/packages/cli/test/sim/endpoints.test.ts @@ -3,10 +3,10 @@ import path from "node:path"; import assert from "node:assert"; import {toHexString} from "@chainsafe/ssz"; import {ApiError, routes} from "@lodestar/api"; -import {SimulationEnvironment} from "../utils/simulation/simulationEnvironment.js"; -import {BeaconClient, ExecutionClient} from "../utils/simulation/interfaces.js"; -import {defineSimTestConfig, logFilesDir} from "../utils/simulation/utils/index.js"; -import {waitForSlot} from "../utils/simulation/utils/network.js"; +import {Simulation} from "../utils/crucible/simulation.js"; +import {BeaconClient, ExecutionClient} from "../utils/crucible/interfaces.js"; +import {defineSimTestConfig, logFilesDir} from "../utils/crucible/utils/index.js"; +import {waitForSlot} from "../utils/crucible/utils/network.js"; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; @@ -19,7 +19,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ initialNodes: 1, }); -const env = await SimulationEnvironment.initWithDefaults( +const env = await Simulation.initWithDefaults( { id: "beacon-endpoints", logsDir: path.join(logFilesDir, "beacon-endpoints"), diff --git a/packages/cli/test/sim/mixedClient.test.ts b/packages/cli/test/sim/mixedClient.test.ts index 85a7ad0eeea..bfb2a5a99b1 100644 --- a/packages/cli/test/sim/mixedClient.test.ts +++ b/packages/cli/test/sim/mixedClient.test.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; -import {SimulationEnvironment} from "../utils/simulation/simulationEnvironment.js"; -import {nodeAssertion} from "../utils/simulation/assertions/nodeAssertion.js"; -import {AssertionMatch, BeaconClient, ExecutionClient, ValidatorClient} from "../utils/simulation/interfaces.js"; -import {defineSimTestConfig, logFilesDir} from "../utils/simulation/utils/index.js"; -import {connectAllNodes, waitForSlot} from "../utils/simulation/utils/network.js"; +import {Simulation} from "../utils/crucible/simulation.js"; +import {nodeAssertion} from "../utils/crucible/assertions/nodeAssertion.js"; +import {Match, BeaconClient, ExecutionClient, ValidatorClient} from "../utils/crucible/interfaces.js"; +import {defineSimTestConfig, logFilesDir} from "../utils/crucible/utils/index.js"; +import {connectAllNodes, waitForSlot} from "../utils/crucible/utils/network.js"; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; @@ -22,7 +22,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ initialNodes: 2, }); -const env = await SimulationEnvironment.initWithDefaults( +const env = await Simulation.initWithDefaults( { id: "mixed-clients", logsDir: path.join(logFilesDir, "mixed-clients"), @@ -58,7 +58,7 @@ const env = await SimulationEnvironment.initWithDefaults( env.tracker.register({ ...nodeAssertion, match: ({slot}) => { - return slot === 1 ? AssertionMatch.Assert | AssertionMatch.Capture | AssertionMatch.Remove : AssertionMatch.None; + return slot === 1 ? Match.Assert | Match.Capture | Match.Remove : Match.None; }, }); diff --git a/packages/cli/test/sim/multiFork.test.ts b/packages/cli/test/sim/multiFork.test.ts index fdedd980e5b..47ad59a165b 100644 --- a/packages/cli/test/sim/multiFork.test.ts +++ b/packages/cli/test/sim/multiFork.test.ts @@ -1,16 +1,16 @@ /* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; -import {AssertionMatch, BeaconClient, ExecutionClient, ValidatorClient} from "../utils/simulation/interfaces.js"; -import {SimulationEnvironment} from "../utils/simulation/simulationEnvironment.js"; -import {defineSimTestConfig, logFilesDir} from "../utils/simulation/utils/index.js"; -import {connectAllNodes, waitForSlot} from "../utils/simulation/utils/network.js"; -import {nodeAssertion} from "../utils/simulation/assertions/nodeAssertion.js"; -import {mergeAssertion} from "../utils/simulation/assertions/mergeAssertion.js"; -import {createForkAssertion} from "../utils/simulation/assertions/forkAssertion.js"; -import {createAccountBalanceAssertion} from "../utils/simulation/assertions/accountBalanceAssertion.js"; -import {createExecutionHeadAssertion} from "../utils/simulation/assertions/executionHeadAssertion.js"; -import {createWithdrawalAssertions} from "../utils/simulation/assertions/withdrawalsAssertion.js"; -import {assertCheckpointSync, assertRangeSync, assertUnknownBlockSync} from "../utils/simulation/utils/syncing.js"; +import {Match, BeaconClient, ExecutionClient, ValidatorClient} from "../utils/crucible/interfaces.js"; +import {Simulation} from "../utils/crucible/simulation.js"; +import {defineSimTestConfig, logFilesDir} from "../utils/crucible/utils/index.js"; +import {connectAllNodes, waitForSlot} from "../utils/crucible/utils/network.js"; +import {nodeAssertion} from "../utils/crucible/assertions/nodeAssertion.js"; +import {mergeAssertion} from "../utils/crucible/assertions/mergeAssertion.js"; +import {createForkAssertion} from "../utils/crucible/assertions/forkAssertion.js"; +import {createAccountBalanceAssertion} from "../utils/crucible/assertions/accountBalanceAssertion.js"; +import {createExecutionHeadAssertion} from "../utils/crucible/assertions/executionHeadAssertion.js"; +import {createWithdrawalAssertions} from "../utils/crucible/assertions/withdrawalsAssertion.js"; +import {assertCheckpointSync, assertRangeSync, assertUnknownBlockSync} from "../utils/crucible/utils/syncing.js"; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; @@ -28,7 +28,7 @@ const {estimatedTimeoutMs, forkConfig} = defineSimTestConfig({ initialNodes: 5, }); -const env = await SimulationEnvironment.initWithDefaults( +const env = await Simulation.initWithDefaults( { id: "multi-fork", logsDir: path.join(logFilesDir, "multi-fork"), @@ -114,7 +114,7 @@ const env = await SimulationEnvironment.initWithDefaults( env.tracker.register({ ...nodeAssertion, match: ({slot}) => { - return slot === 1 ? AssertionMatch.Assert | AssertionMatch.Capture | AssertionMatch.Remove : AssertionMatch.None; + return slot === 1 ? Match.Assert | Match.Capture | Match.Remove : Match.None; }, }); @@ -122,9 +122,7 @@ env.tracker.register({ ...mergeAssertion, match: ({slot}) => { // Check at the end of bellatrix fork, merge should happen by then - return slot === env.clock.getLastSlotOfEpoch(bellatrixForkEpoch) - ? AssertionMatch.Assert | AssertionMatch.Remove - : AssertionMatch.None; + return slot === env.clock.getLastSlotOfEpoch(bellatrixForkEpoch) ? Match.Assert | Match.Remove : Match.None; }, }); diff --git a/packages/cli/test/utils/simulation/README.md b/packages/cli/test/utils/crucible/README.md similarity index 98% rename from packages/cli/test/utils/simulation/README.md rename to packages/cli/test/utils/crucible/README.md index b809cfce91f..a8d8a8e2158 100644 --- a/packages/cli/test/utils/simulation/README.md +++ b/packages/cli/test/utils/crucible/README.md @@ -1,4 +1,6 @@ -# Lodestar Simulation Test +# Crucible by Lodestar + +> a test of faith, patience, or strength Lodestar simulation tests allows to setup a small, local devnet for the variety of Consensus and Execution Layer clients. We use the `minimal` preset for all CL clients. Following clients are currently supported. diff --git a/packages/cli/test/utils/simulation/assertions/accountBalanceAssertion.ts b/packages/cli/test/utils/crucible/assertions/accountBalanceAssertion.ts similarity index 85% rename from packages/cli/test/utils/simulation/assertions/accountBalanceAssertion.ts rename to packages/cli/test/utils/crucible/assertions/accountBalanceAssertion.ts index 1866d52a847..e6c4f4c744e 100644 --- a/packages/cli/test/utils/simulation/assertions/accountBalanceAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/accountBalanceAssertion.ts @@ -1,5 +1,5 @@ import {EL_GENESIS_ACCOUNT} from "../constants.js"; -import {AssertionMatch, AssertionResult, NodePair, SimulationAssertion} from "../interfaces.js"; +import {Match, AssertionResult, NodePair, Assertion} from "../interfaces.js"; const transactionAmount = BigInt(2441406250); @@ -13,13 +13,13 @@ export function createAccountBalanceAssertion({ sendTransactionsAtSlot: number[]; validateTotalBalanceAt: number[]; targetNode: NodePair; -}): SimulationAssertion<`accountBalance_${typeof address}`, bigint> { +}): Assertion<`accountBalance_${typeof address}`, bigint> { return { id: `accountBalance_${address}`, match({slot, node}) { - if (sendTransactionsAtSlot.includes(slot) && node.id === targetNode.id) return AssertionMatch.Capture; - if (validateTotalBalanceAt.includes(slot) && node.id === targetNode.id) return AssertionMatch.Assert; - return AssertionMatch.None; + if (sendTransactionsAtSlot.includes(slot) && node.id === targetNode.id) return Match.Capture; + if (validateTotalBalanceAt.includes(slot) && node.id === targetNode.id) return Match.Assert; + return Match.None; }, async capture({node}) { await node.execution.provider?.eth.sendTransaction({ diff --git a/packages/cli/test/utils/simulation/assertions/blobsAssertion.ts b/packages/cli/test/utils/crucible/assertions/blobsAssertion.ts similarity index 92% rename from packages/cli/test/utils/simulation/assertions/blobsAssertion.ts rename to packages/cli/test/utils/crucible/assertions/blobsAssertion.ts index e714f0db8d7..99700827268 100644 --- a/packages/cli/test/utils/simulation/assertions/blobsAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/blobsAssertion.ts @@ -1,7 +1,7 @@ import {randomBytes} from "node:crypto"; import {ApiError} from "@lodestar/api"; import {fromHex, toHex} from "@lodestar/utils"; -import {SimulationAssertion, AssertionMatch, AssertionResult, NodePair} from "../interfaces.js"; +import {Assertion, Match, AssertionResult, NodePair} from "../interfaces.js"; import {EL_GENESIS_ACCOUNT, EL_GENESIS_SECRET_KEY, SIM_ENV_CHAIN_ID} from "../constants.js"; import {generateBlobsForTransaction} from "../utils/blobs.js"; import {BlobsEIP4844Transaction} from "../web3js/blobsEIP4844Transaction.js"; @@ -12,16 +12,16 @@ const sentBlobs: Uint8Array[] = []; export function createBlobsAssertion( nodes: NodePair[], {sendBlobsAtSlot, validateBlobsAt}: {sendBlobsAtSlot: number; validateBlobsAt: number} -): SimulationAssertion { +): Assertion { return { id: `blobs-${nodes.map((n) => n.id).join("-")}`, match: ({slot}) => { // Run capture every sendBlobsAtSlot -> validateBlobsAt and validate only at validateBlobsAt return slot === validateBlobsAt - ? AssertionMatch.Capture | AssertionMatch.Assert + ? Match.Capture | Match.Assert : slot >= sendBlobsAtSlot && slot <= validateBlobsAt - ? AssertionMatch.Capture - : AssertionMatch.None; + ? Match.Capture + : Match.None; }, async capture({slot, node}) { diff --git a/packages/cli/test/utils/simulation/assertions/defaults/attestationCountAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/attestationCountAssertion.ts similarity index 91% rename from packages/cli/test/utils/simulation/assertions/defaults/attestationCountAssertion.ts rename to packages/cli/test/utils/crucible/assertions/defaults/attestationCountAssertion.ts index 9c01a6bdc3a..5d0f7a268f8 100644 --- a/packages/cli/test/utils/simulation/assertions/defaults/attestationCountAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/attestationCountAssertion.ts @@ -1,18 +1,14 @@ import {MAX_COMMITTEES_PER_SLOT} from "@lodestar/params"; -import {AssertionMatch, AssertionResult, SimulationAssertion} from "../../interfaces.js"; +import {Match, AssertionResult, Assertion} from "../../interfaces.js"; import {inclusionDelayAssertion, expectedMaxInclusionDelay} from "./inclusionDelayAssertion.js"; export const expectedMinAttestationCount = MAX_COMMITTEES_PER_SLOT - 1; -export const attestationsCountAssertion: SimulationAssertion< - "attestationsCount", - number, - [typeof inclusionDelayAssertion] -> = { +export const attestationsCountAssertion: Assertion<"attestationsCount", number, [typeof inclusionDelayAssertion]> = { id: "attestationsCount", match: () => { // TODO : Disable the assertion for now as the attestations count could be different per slot. - return AssertionMatch.Capture; + return Match.Capture; }, dependencies: [inclusionDelayAssertion], diff --git a/packages/cli/test/utils/simulation/assertions/defaults/attestationParticipationAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/attestationParticipationAssertion.ts similarity index 92% rename from packages/cli/test/utils/simulation/assertions/defaults/attestationParticipationAssertion.ts rename to packages/cli/test/utils/crucible/assertions/defaults/attestationParticipationAssertion.ts index 38403f7dc69..e44cb6cf562 100644 --- a/packages/cli/test/utils/simulation/assertions/defaults/attestationParticipationAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/attestationParticipationAssertion.ts @@ -2,7 +2,7 @@ import {ApiError} from "@lodestar/api"; import {TIMELY_HEAD_FLAG_INDEX, TIMELY_SOURCE_FLAG_INDEX, TIMELY_TARGET_FLAG_INDEX} from "@lodestar/params"; import {isActiveValidator} from "@lodestar/state-transition"; import {altair} from "@lodestar/types"; -import {AssertionMatch, AssertionResult, SimulationAssertion} from "../../interfaces.js"; +import {Match, AssertionResult, Assertion} from "../../interfaces.js"; const TIMELY_HEAD = 1 << TIMELY_HEAD_FLAG_INDEX; const TIMELY_SOURCE = 1 << TIMELY_SOURCE_FLAG_INDEX; @@ -10,7 +10,7 @@ const TIMELY_TARGET = 1 << TIMELY_TARGET_FLAG_INDEX; const expectedMinParticipationRate = 0.8; -export const attestationParticipationAssertion: SimulationAssertion< +export const attestationParticipationAssertion: Assertion< "attestationParticipation", {head: number; source: number; target: number} > = { @@ -19,10 +19,10 @@ export const attestationParticipationAssertion: SimulationAssertion< // Capture data only when epoch and one extra slot passed // Only assert at first slot of an epoch if (epoch >= forkConfig.ALTAIR_FORK_EPOCH && clock.isFirstSlotOfEpoch(slot)) { - return AssertionMatch.Capture | AssertionMatch.Assert; + return Match.Capture | Match.Assert; } - return AssertionMatch.None; + return Match.None; }, async capture({node, epoch}) { diff --git a/packages/cli/test/utils/simulation/assertions/defaults/connectedPeerCountAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/connectedPeerCountAssertion.ts similarity index 79% rename from packages/cli/test/utils/simulation/assertions/defaults/connectedPeerCountAssertion.ts rename to packages/cli/test/utils/crucible/assertions/defaults/connectedPeerCountAssertion.ts index 8669938c525..d3f6fe6038f 100644 --- a/packages/cli/test/utils/simulation/assertions/defaults/connectedPeerCountAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/connectedPeerCountAssertion.ts @@ -1,8 +1,8 @@ import {ApiError} from "@lodestar/api"; -import {AssertionResult, SimulationAssertion} from "../../interfaces.js"; +import {AssertionResult, Assertion} from "../../interfaces.js"; import {everySlotMatcher} from "../matchers.js"; -export const connectedPeerCountAssertion: SimulationAssertion<"connectedPeerCount", number> = { +export const connectedPeerCountAssertion: Assertion<"connectedPeerCount", number> = { id: "connectedPeerCount", match: everySlotMatcher, async capture({node}) { diff --git a/packages/cli/test/utils/simulation/assertions/defaults/finalizedAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/finalizedAssertion.ts similarity index 85% rename from packages/cli/test/utils/simulation/assertions/defaults/finalizedAssertion.ts rename to packages/cli/test/utils/crucible/assertions/defaults/finalizedAssertion.ts index 4d07e06193d..44bd01dd865 100644 --- a/packages/cli/test/utils/simulation/assertions/defaults/finalizedAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/finalizedAssertion.ts @@ -1,9 +1,9 @@ import {ApiError} from "@lodestar/api"; import {Slot} from "@lodestar/types"; -import {AssertionResult, SimulationAssertion} from "../../interfaces.js"; +import {AssertionResult, Assertion} from "../../interfaces.js"; import {everySlotMatcher} from "../matchers.js"; -export const finalizedAssertion: SimulationAssertion<"finalized", Slot> = { +export const finalizedAssertion: Assertion<"finalized", Slot> = { id: "finalized", match: everySlotMatcher, async capture({node}) { diff --git a/packages/cli/test/utils/simulation/assertions/defaults/headAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/headAssertion.ts similarity index 91% rename from packages/cli/test/utils/simulation/assertions/defaults/headAssertion.ts rename to packages/cli/test/utils/crucible/assertions/defaults/headAssertion.ts index 8d493637d22..9c95b765814 100644 --- a/packages/cli/test/utils/simulation/assertions/defaults/headAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/headAssertion.ts @@ -1,7 +1,7 @@ import {ApiError} from "@lodestar/api"; import {RootHex, Slot} from "@lodestar/types"; import {toHexString} from "@lodestar/utils"; -import {AssertionResult, SimulationAssertion} from "../../interfaces.js"; +import {AssertionResult, Assertion} from "../../interfaces.js"; import {everySlotMatcher} from "../matchers.js"; export interface HeadSummary { @@ -9,7 +9,7 @@ export interface HeadSummary { slot: Slot; } -export const headAssertion: SimulationAssertion<"head", HeadSummary> = { +export const headAssertion: Assertion<"head", HeadSummary> = { id: "head", match: everySlotMatcher, async capture({node}) { diff --git a/packages/cli/test/utils/simulation/assertions/defaults/inclusionDelayAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/inclusionDelayAssertion.ts similarity index 88% rename from packages/cli/test/utils/simulation/assertions/defaults/inclusionDelayAssertion.ts rename to packages/cli/test/utils/crucible/assertions/defaults/inclusionDelayAssertion.ts index 554df0e31ca..e3ec467099b 100644 --- a/packages/cli/test/utils/simulation/assertions/defaults/inclusionDelayAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/inclusionDelayAssertion.ts @@ -1,10 +1,10 @@ -import {AssertionResult, SimulationAssertion} from "../../interfaces.js"; +import {AssertionResult, Assertion} from "../../interfaces.js"; import {avg} from "../../utils/index.js"; import {everySlotMatcher} from "../matchers.js"; export const expectedMaxInclusionDelay = 2; -export const inclusionDelayAssertion: SimulationAssertion<"inclusionDelay", number> = { +export const inclusionDelayAssertion: Assertion<"inclusionDelay", number> = { id: "inclusionDelay", match: everySlotMatcher, async capture(input) { diff --git a/packages/cli/test/utils/simulation/assertions/defaults/index.ts b/packages/cli/test/utils/crucible/assertions/defaults/index.ts similarity index 100% rename from packages/cli/test/utils/simulation/assertions/defaults/index.ts rename to packages/cli/test/utils/crucible/assertions/defaults/index.ts diff --git a/packages/cli/test/utils/simulation/assertions/defaults/missedBlocksAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/missedBlocksAssertion.ts similarity index 82% rename from packages/cli/test/utils/simulation/assertions/defaults/missedBlocksAssertion.ts rename to packages/cli/test/utils/crucible/assertions/defaults/missedBlocksAssertion.ts index 299280a37c7..1209a6469ca 100644 --- a/packages/cli/test/utils/simulation/assertions/defaults/missedBlocksAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/missedBlocksAssertion.ts @@ -1,12 +1,12 @@ import {isNullish} from "../../../../utils.js"; -import {AssertionMatch, AssertionResult, SimulationAssertion} from "../../interfaces.js"; +import {Match, AssertionResult, Assertion} from "../../interfaces.js"; import {arrayEquals} from "../../utils/index.js"; import {headAssertion} from "./headAssertion.js"; -export const missedBlocksAssertion: SimulationAssertion<"missedBlocks", number[], [typeof headAssertion]> = { +export const missedBlocksAssertion: Assertion<"missedBlocks", number[], [typeof headAssertion]> = { id: "missedBlocks", match: ({clock, slot}) => { - return clock.isLastSlotOfEpoch(slot) ? AssertionMatch.Capture | AssertionMatch.Assert : AssertionMatch.None; + return clock.isLastSlotOfEpoch(slot) ? Match.Capture | Match.Assert : Match.None; }, dependencies: [headAssertion], async capture({node, epoch, slot, dependantStores, clock}) { diff --git a/packages/cli/test/utils/simulation/assertions/defaults/syncCommitteeParticipationAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/syncCommitteeParticipationAssertion.ts similarity index 85% rename from packages/cli/test/utils/simulation/assertions/defaults/syncCommitteeParticipationAssertion.ts rename to packages/cli/test/utils/crucible/assertions/defaults/syncCommitteeParticipationAssertion.ts index 5cce7554d73..83b945da0b0 100644 --- a/packages/cli/test/utils/simulation/assertions/defaults/syncCommitteeParticipationAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/syncCommitteeParticipationAssertion.ts @@ -1,18 +1,18 @@ import {ForkName} from "@lodestar/params"; import {altair} from "@lodestar/types"; -import {AssertionMatch, AssertionResult, SimulationAssertion} from "../../interfaces.js"; +import {Match, AssertionResult, Assertion} from "../../interfaces.js"; import {avg} from "../../utils/index.js"; // Until we identity and fix the following issue, reducing the expected sync committee participation rate from 0.9 to 0.75 // https://github.com/ChainSafe/lodestar/issues/6432 export const expectedMinSyncParticipationRate = 0.75; -export const syncCommitteeParticipationAssertion: SimulationAssertion<"syncCommitteeParticipation", number> = { +export const syncCommitteeParticipationAssertion: Assertion<"syncCommitteeParticipation", number> = { id: "syncCommitteeParticipation", match: ({slot, clock, fork}) => { - if (fork === ForkName.phase0) return AssertionMatch.None; + if (fork === ForkName.phase0) return Match.None; - return clock.isLastSlotOfEpoch(slot) ? AssertionMatch.Capture | AssertionMatch.Assert : AssertionMatch.Capture; + return clock.isLastSlotOfEpoch(slot) ? Match.Capture | Match.Assert : Match.Capture; }, async capture({block}) { diff --git a/packages/cli/test/utils/simulation/assertions/executionHeadAssertion.ts b/packages/cli/test/utils/crucible/assertions/executionHeadAssertion.ts similarity index 86% rename from packages/cli/test/utils/simulation/assertions/executionHeadAssertion.ts rename to packages/cli/test/utils/crucible/assertions/executionHeadAssertion.ts index cef08bb3824..391fb27e658 100644 --- a/packages/cli/test/utils/simulation/assertions/executionHeadAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/executionHeadAssertion.ts @@ -1,21 +1,21 @@ import {ApiError} from "@lodestar/api"; import {toHex} from "@lodestar/utils"; import {bellatrix} from "@lodestar/types"; -import {AssertionMatch, AssertionResult, SimulationAssertion} from "../interfaces.js"; +import {Match, AssertionResult, Assertion} from "../interfaces.js"; export function createExecutionHeadAssertion({ checkForSlot, }: { checkForSlot: number[]; -}): SimulationAssertion< +}): Assertion< "executionHead", {executionHead: {hash: string}; consensusHead: {executionPayload: {blockHash: string}}} > { return { id: "executionHead", match({slot}) { - if (checkForSlot.includes(slot)) return AssertionMatch.Capture | AssertionMatch.Assert; - return AssertionMatch.None; + if (checkForSlot.includes(slot)) return Match.Capture | Match.Assert; + return Match.None; }, async capture({node}) { const blockNumber = await node.execution.provider?.eth.getBlockNumber(); diff --git a/packages/cli/test/utils/simulation/assertions/forkAssertion.ts b/packages/cli/test/utils/crucible/assertions/forkAssertion.ts similarity index 82% rename from packages/cli/test/utils/simulation/assertions/forkAssertion.ts rename to packages/cli/test/utils/crucible/assertions/forkAssertion.ts index c78a617efce..5dc804c642f 100644 --- a/packages/cli/test/utils/simulation/assertions/forkAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/forkAssertion.ts @@ -2,15 +2,15 @@ import {ApiError} from "@lodestar/api"; import {ForkName} from "@lodestar/params"; import {Epoch} from "@lodestar/types"; import {toHexString} from "@lodestar/utils"; -import {AssertionMatch, AssertionResult, SimulationAssertion} from "../interfaces.js"; +import {Match, AssertionResult, Assertion} from "../interfaces.js"; -export function createForkAssertion(fork: ForkName, epoch: Epoch): SimulationAssertion { +export function createForkAssertion(fork: ForkName, epoch: Epoch): Assertion { return { id: `fork-${fork}`, match: ({slot, clock}) => { return clock.isFirstSlotOfEpoch(slot) && epoch === clock.getEpochForSlot(slot) - ? AssertionMatch.Assert | AssertionMatch.Remove - : AssertionMatch.None; + ? Match.Assert | Match.Remove + : Match.None; }, assert: async ({node, slot, forkConfig}) => { const errors: AssertionResult[] = []; diff --git a/packages/cli/test/utils/simulation/assertions/lighthousePeerScoreAssertion.ts b/packages/cli/test/utils/crucible/assertions/lighthousePeerScoreAssertion.ts similarity index 91% rename from packages/cli/test/utils/simulation/assertions/lighthousePeerScoreAssertion.ts rename to packages/cli/test/utils/crucible/assertions/lighthousePeerScoreAssertion.ts index d7b5e4d6c08..1b6837a881e 100644 --- a/packages/cli/test/utils/simulation/assertions/lighthousePeerScoreAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/lighthousePeerScoreAssertion.ts @@ -1,12 +1,12 @@ import {ApiError} from "@lodestar/api"; -import {AssertionResult, BeaconClient, LighthouseAPI, NodePair, SimulationAssertion} from "../interfaces.js"; +import {AssertionResult, BeaconClient, LighthouseAPI, NodePair, Assertion} from "../interfaces.js"; import {neverMatcher} from "./matchers.js"; const MIN_GOSSIPSUB_SCORE = 10; let peersIdMapCache: Record; -export const lighthousePeerScoreAssertion: SimulationAssertion<"lighthousePeerScore", {gossipsubScore: number}> = { +export const lighthousePeerScoreAssertion: Assertion<"lighthousePeerScore", {gossipsubScore: number}> = { id: "lighthousePeerScore", match: neverMatcher, async assert({nodes, node}) { diff --git a/packages/cli/test/utils/crucible/assertions/matchers.ts b/packages/cli/test/utils/crucible/assertions/matchers.ts new file mode 100644 index 00000000000..bc51f3fb76a --- /dev/null +++ b/packages/cli/test/utils/crucible/assertions/matchers.ts @@ -0,0 +1,15 @@ +import {Match, Matcher} from "../interfaces.js"; + +export const everySlotMatcher: Matcher = ({slot}) => (slot >= 0 ? Match.Capture | Match.Assert : Match.None); + +export const everyEpochMatcher: Matcher = ({slot, clock}) => + clock.isLastSlotOfEpoch(slot) ? Match.Capture | Match.Assert : Match.Capture; + +export const neverMatcher: Matcher = () => Match.None; + +export const onceOnSlotMatcher = + (userSlot: number): Matcher => + ({slot}) => + slot === userSlot ? Match.Capture | Match.Assert : Match.None; + +export const onceOnStartupMatcher = onceOnSlotMatcher(1); diff --git a/packages/cli/test/utils/simulation/assertions/mergeAssertion.ts b/packages/cli/test/utils/crucible/assertions/mergeAssertion.ts similarity index 83% rename from packages/cli/test/utils/simulation/assertions/mergeAssertion.ts rename to packages/cli/test/utils/crucible/assertions/mergeAssertion.ts index a7b522504df..d7a90857ae2 100644 --- a/packages/cli/test/utils/simulation/assertions/mergeAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/mergeAssertion.ts @@ -1,9 +1,9 @@ import {ApiError} from "@lodestar/api"; import {BeaconStateAllForks, isExecutionStateType, isMergeTransitionComplete} from "@lodestar/state-transition"; -import {AssertionResult, SimulationAssertion} from "../interfaces.js"; +import {AssertionResult, Assertion} from "../interfaces.js"; import {neverMatcher} from "./matchers.js"; -export const mergeAssertion: SimulationAssertion<"merge", string> = { +export const mergeAssertion: Assertion<"merge", string> = { id: "merge", // Include into particular test with custom condition match: neverMatcher, diff --git a/packages/cli/test/utils/simulation/assertions/nodeAssertion.ts b/packages/cli/test/utils/crucible/assertions/nodeAssertion.ts similarity index 90% rename from packages/cli/test/utils/simulation/assertions/nodeAssertion.ts rename to packages/cli/test/utils/crucible/assertions/nodeAssertion.ts index 25784b688d4..7a449b3f669 100644 --- a/packages/cli/test/utils/simulation/assertions/nodeAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/nodeAssertion.ts @@ -1,11 +1,11 @@ import type {SecretKey} from "@chainsafe/bls/types"; import {routes} from "@lodestar/api/beacon"; import {ApiError} from "@lodestar/api"; -import {AssertionResult, ValidatorClientKeys, SimulationAssertion, ValidatorClient} from "../interfaces.js"; +import {AssertionResult, ValidatorClientKeys, Assertion, ValidatorClient} from "../interfaces.js"; import {arrayEquals} from "../utils/index.js"; import {neverMatcher} from "./matchers.js"; -export const nodeAssertion: SimulationAssertion<"node", {health: number; keyManagerKeys: string[]}> = { +export const nodeAssertion: Assertion<"node", {health: number; keyManagerKeys: string[]}> = { id: "node", // Include into particular test with custom condition match: neverMatcher, diff --git a/packages/cli/test/utils/simulation/assertions/withdrawalsAssertion.ts b/packages/cli/test/utils/crucible/assertions/withdrawalsAssertion.ts similarity index 93% rename from packages/cli/test/utils/simulation/assertions/withdrawalsAssertion.ts rename to packages/cli/test/utils/crucible/assertions/withdrawalsAssertion.ts index 6f7be91bf3c..7daa3868282 100644 --- a/packages/cli/test/utils/simulation/assertions/withdrawalsAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/withdrawalsAssertion.ts @@ -1,7 +1,7 @@ import {capella} from "@lodestar/types"; import {ApiError} from "@lodestar/api"; import {MAX_WITHDRAWALS_PER_PAYLOAD} from "@lodestar/params"; -import {AssertionMatch, AssertionResult, SimulationAssertion} from "../interfaces.js"; +import {Match, AssertionResult, Assertion} from "../interfaces.js"; type WithdrawalsData = { withdrawalCount: number; @@ -11,14 +11,13 @@ type WithdrawalsData = { export function createWithdrawalAssertions( nodeId: T -): SimulationAssertion<`withdrawals_${T}`, WithdrawalsData> { +): Assertion<`withdrawals_${T}`, WithdrawalsData> { return { id: `withdrawals_${nodeId}`, match({forkConfig, epoch, node}) { - if (nodeId === node.id && epoch === forkConfig.CAPELLA_FORK_EPOCH) - return AssertionMatch.Capture | AssertionMatch.Assert; + if (nodeId === node.id && epoch === forkConfig.CAPELLA_FORK_EPOCH) return Match.Capture | Match.Assert; - return AssertionMatch.None; + return Match.None; }, async capture({block, node, slot}) { const withdrawals = (block as capella.SignedBeaconBlock).message.body.executionPayload.withdrawals; diff --git a/packages/cli/test/utils/simulation/clients/beacon/index.ts b/packages/cli/test/utils/crucible/clients/beacon/index.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/beacon/index.ts rename to packages/cli/test/utils/crucible/clients/beacon/index.ts diff --git a/packages/cli/test/utils/simulation/clients/beacon/lighthouse.ts b/packages/cli/test/utils/crucible/clients/beacon/lighthouse.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/beacon/lighthouse.ts rename to packages/cli/test/utils/crucible/clients/beacon/lighthouse.ts diff --git a/packages/cli/test/utils/simulation/clients/beacon/lodestar.ts b/packages/cli/test/utils/crucible/clients/beacon/lodestar.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/beacon/lodestar.ts rename to packages/cli/test/utils/crucible/clients/beacon/lodestar.ts diff --git a/packages/cli/test/utils/simulation/clients/execution/geth.ts b/packages/cli/test/utils/crucible/clients/execution/geth.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/execution/geth.ts rename to packages/cli/test/utils/crucible/clients/execution/geth.ts diff --git a/packages/cli/test/utils/simulation/clients/execution/index.ts b/packages/cli/test/utils/crucible/clients/execution/index.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/execution/index.ts rename to packages/cli/test/utils/crucible/clients/execution/index.ts diff --git a/packages/cli/test/utils/simulation/clients/execution/mock.ts b/packages/cli/test/utils/crucible/clients/execution/mock.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/execution/mock.ts rename to packages/cli/test/utils/crucible/clients/execution/mock.ts diff --git a/packages/cli/test/utils/simulation/clients/execution/nethermind.ts b/packages/cli/test/utils/crucible/clients/execution/nethermind.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/execution/nethermind.ts rename to packages/cli/test/utils/crucible/clients/execution/nethermind.ts diff --git a/packages/cli/test/utils/simulation/clients/validator/index.ts b/packages/cli/test/utils/crucible/clients/validator/index.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/validator/index.ts rename to packages/cli/test/utils/crucible/clients/validator/index.ts diff --git a/packages/cli/test/utils/simulation/clients/validator/lighthouse.ts b/packages/cli/test/utils/crucible/clients/validator/lighthouse.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/validator/lighthouse.ts rename to packages/cli/test/utils/crucible/clients/validator/lighthouse.ts diff --git a/packages/cli/test/utils/simulation/clients/validator/lodestar.ts b/packages/cli/test/utils/crucible/clients/validator/lodestar.ts similarity index 100% rename from packages/cli/test/utils/simulation/clients/validator/lodestar.ts rename to packages/cli/test/utils/crucible/clients/validator/lodestar.ts diff --git a/packages/cli/test/utils/simulation/constants.ts b/packages/cli/test/utils/crucible/constants.ts similarity index 100% rename from packages/cli/test/utils/simulation/constants.ts rename to packages/cli/test/utils/crucible/constants.ts diff --git a/packages/cli/test/utils/simulation/epochClock.ts b/packages/cli/test/utils/crucible/epochClock.ts similarity index 100% rename from packages/cli/test/utils/simulation/epochClock.ts rename to packages/cli/test/utils/crucible/epochClock.ts diff --git a/packages/cli/test/utils/simulation/externalSignerServer.ts b/packages/cli/test/utils/crucible/externalSignerServer.ts similarity index 100% rename from packages/cli/test/utils/simulation/externalSignerServer.ts rename to packages/cli/test/utils/crucible/externalSignerServer.ts diff --git a/packages/cli/test/utils/simulation/interfaces.ts b/packages/cli/test/utils/crucible/interfaces.ts similarity index 88% rename from packages/cli/test/utils/simulation/interfaces.ts rename to packages/cli/test/utils/crucible/interfaces.ts index 4fd9c0065c4..a7934f962d4 100644 --- a/packages/cli/test/utils/simulation/interfaces.ts +++ b/packages/cli/test/utils/crucible/interfaces.ts @@ -317,24 +317,23 @@ export interface AssertionInput { node: NodePair; } -export interface SimulationCaptureInput> extends AssertionInput { +export interface CaptureInput> extends AssertionInput { block: allForks.SignedBeaconBlock; dependantStores: D; } -export interface SimulationAssertionInput = Record> - extends AssertionInput { +export interface AssertInput = Record> extends AssertionInput { nodes: NodePair[]; store: Record; dependantStores: D; } -export interface SimulationDumpInput extends Omit { +export interface DumpInput extends Omit { nodes: NodePair[]; store: Record>; } -export type SimulationMatcherInput = AssertionInput; +export type MatcherInput = AssertionInput; /** * Bitwise flag to indicate what to do with the assertion @@ -345,45 +344,42 @@ export type SimulationMatcherInput = AssertionInput; * @example * Capture and assert: `AssertionMatch.Capture | AssertionMatch.Assert` */ -export enum AssertionMatch { +export enum Match { None = 0, Capture = 1 << 0, Assert = 1 << 1, Remove = 1 << 2, } -export type AssertionMatcher = (input: SimulationMatcherInput) => AssertionMatch; -export type ExtractAssertionType = - T extends SimulationAssertion ? (A extends I ? B : never) : never; -export type ExtractAssertionId = T extends SimulationAssertion ? A : never; +export type Matcher = (input: MatcherInput) => Match; +export type ExtractAssertionType = T extends Assertion ? (A extends I ? B : never) : never; +export type ExtractAssertionId = T extends Assertion ? A : never; export type StoreType = Record< AssertionId, Record> >; -export type StoreTypes> = { +export type StoreTypes> = { [Id in IDs]: Record | undefined>>; }; -export interface SimulationAssertion< +export interface Assertion< IdType extends string = string, ValueType = unknown, - Dependencies extends SimulationAssertion[] = SimulationAssertion[], + Dependencies extends Assertion[] = Assertion[], > { readonly id: IdType; - capture?( - input: SimulationCaptureInput & StoreType> - ): Promise; - match: AssertionMatcher; + capture?(input: CaptureInput & StoreType>): Promise; + match: Matcher; assert( - input: SimulationAssertionInput & StoreType> + input: AssertInput & StoreType> ): Promise; dependencies?: Dependencies; // Use to dump the data to CSV files, as each assertion implementation knows // how to make the dump more readable, so we define it in assertion // Return object as key-value pair for file name as dump data - dump?(input: SimulationDumpInput): Promise>; + dump?(input: DumpInput): Promise>; } export type AssertionResult = string | [string, Record]; -export interface SimulationAssertionError { +export interface AssertionError { slot: Slot; epoch: Epoch; assertionId: string; @@ -402,14 +398,14 @@ export type Eth1GenesisBlock = { alloc: Record; }; -export abstract class SimulationReporter { +export abstract class SimulationReporter { constructor( protected options: { clock: EpochClock; forkConfig: ChainForkConfig; stores: StoreTypes; nodes: NodePair[]; - errors: SimulationAssertionError[]; + errors: AssertionError[]; logger: Logger; } ) {} diff --git a/packages/cli/test/utils/simulation/runner/childProcessRunner.ts b/packages/cli/test/utils/crucible/runner/childProcessRunner.ts similarity index 100% rename from packages/cli/test/utils/simulation/runner/childProcessRunner.ts rename to packages/cli/test/utils/crucible/runner/childProcessRunner.ts diff --git a/packages/cli/test/utils/simulation/runner/dockerRunner.ts b/packages/cli/test/utils/crucible/runner/dockerRunner.ts similarity index 100% rename from packages/cli/test/utils/simulation/runner/dockerRunner.ts rename to packages/cli/test/utils/crucible/runner/dockerRunner.ts diff --git a/packages/cli/test/utils/simulation/runner/index.ts b/packages/cli/test/utils/crucible/runner/index.ts similarity index 100% rename from packages/cli/test/utils/simulation/runner/index.ts rename to packages/cli/test/utils/crucible/runner/index.ts diff --git a/packages/cli/test/utils/simulation/simulationEnvironment.ts b/packages/cli/test/utils/crucible/simulation.ts similarity index 98% rename from packages/cli/test/utils/simulation/simulationEnvironment.ts rename to packages/cli/test/utils/crucible/simulation.ts index 7b62870f806..7a2343b6082 100644 --- a/packages/cli/test/utils/simulation/simulationEnvironment.ts +++ b/packages/cli/test/utils/crucible/simulation.ts @@ -38,7 +38,7 @@ interface StartOpts { runTimeoutMs: number; } -export class SimulationEnvironment { +export class Simulation { readonly nodes: NodePair[] = []; readonly clock: EpochClock; readonly tracker: SimulationTracker; @@ -75,7 +75,7 @@ export class SimulationEnvironment { this.externalSigner = new ExternalSignerServer([]); this.runner = new Runner({logsDir: this.options.logsDir, logger: this.logger.child({module: "runner"})}); - this.tracker = SimulationTracker.initWithDefaultAssertions({ + this.tracker = SimulationTracker.initWithDefaults({ logsDir: options.logsDir, logger: this.logger, nodes: [], @@ -88,8 +88,8 @@ export class SimulationEnvironment { static async initWithDefaults( {forkConfig, logsDir, id, trustedSetup}: SimulationInitOptions, clients: NodePairDefinition[] - ): Promise { - const env = new SimulationEnvironment(forkConfig, { + ): Promise { + const env = new Simulation(forkConfig, { logsDir, id, genesisTime: Math.floor(Date.now() / 1000), diff --git a/packages/cli/test/utils/simulation/simulationTracker.ts b/packages/cli/test/utils/crucible/simulationTracker.ts similarity index 94% rename from packages/cli/test/utils/simulation/simulationTracker.ts rename to packages/cli/test/utils/crucible/simulationTracker.ts index 909f92ede8e..3533015d58d 100644 --- a/packages/cli/test/utils/simulation/simulationTracker.ts +++ b/packages/cli/test/utils/crucible/simulationTracker.ts @@ -9,12 +9,12 @@ import {LoggerNode} from "@lodestar/logger/node"; import {isNullish} from "../../utils.js"; import {EpochClock} from "./epochClock.js"; import { - AssertionMatch, + Match, AtLeast, NodeId, NodePair, - SimulationAssertion, - SimulationAssertionError, + Assertion, + AssertionError, SimulationReporter, StoreType, StoreTypes, @@ -54,10 +54,7 @@ const eventStreamEventMap = { type Stores = StoreTypes & StoreType; -export function getStoresForAssertions( - stores: Stores, - dependencies: D -): StoreTypes { +export function getStoresForAssertions(stores: Stores, dependencies: D): StoreTypes { const filterStores: Record = {}; for (const assertion of dependencies) { @@ -90,9 +87,9 @@ export class SimulationTracker { private forkConfig: ChainForkConfig; private running = false; - private errors: SimulationAssertionError[] = []; + private errors: AssertionError[] = []; private stores: Stores; - private assertions: SimulationAssertion[]; + private assertions: Assertion[]; private assertionIdsMap: Record = {}; private constructor({signal, nodes, clock, config, logger, logsDir}: SimulationTrackerInitOptions) { this.signal = signal; @@ -103,7 +100,7 @@ export class SimulationTracker { this.logger = logger.child({module: "tracker"}); this.stores = {} as StoreTypes & StoreType; - this.assertions = [] as SimulationAssertion[]; + this.assertions = [] as Assertion[]; this.reporter = new TableReporter({ logger: this.logger.child({module: "reporter"}), clock: this.clock, @@ -114,7 +111,7 @@ export class SimulationTracker { }); } - static initWithDefaultAssertions(opts: SimulationTrackerInitOptions): SimulationTracker { + static initWithDefaults(opts: SimulationTrackerInitOptions): SimulationTracker { const tracker = new SimulationTracker(opts); for (const assertion of defaultAssertions) { @@ -230,7 +227,7 @@ export class SimulationTracker { this.emitter.once(`${node.beacon.id}:slot:${slot}`, cb); } - register(assertion: SimulationAssertion): void { + register(assertion: Assertion): void { if (assertion.id in this.assertionIdsMap) { throw new Error(`The assertion "${assertion.id}" is already registered`); } @@ -250,7 +247,7 @@ export class SimulationTracker { } } - record(error: AtLeast): void { + record(error: AtLeast): void { this.errors.push({ ...error, epoch: error.epoch ?? this.clock.getEpochForSlot(error.slot), @@ -336,7 +333,7 @@ export class SimulationTracker { fork: this.forkConfig.getForkName(slot), }); - if (match & AssertionMatch.None || !(match & AssertionMatch.Capture)) continue; + if (match & Match.None || !(match & Match.Capture)) continue; if (!assertion.capture) { throw new Error(`Assertion "${assertion.id}" has no capture function`); @@ -383,7 +380,7 @@ export class SimulationTracker { fork: this.forkConfig.getForkName(slot), }); - if (match & AssertionMatch.None || !(match & AssertionMatch.Assert)) continue; + if (match & Match.None || !(match & Match.Assert)) continue; try { const errors = await assertion.assert({ diff --git a/packages/cli/test/utils/simulation/tableRenderer.ts b/packages/cli/test/utils/crucible/tableRenderer.ts similarity index 100% rename from packages/cli/test/utils/simulation/tableRenderer.ts rename to packages/cli/test/utils/crucible/tableRenderer.ts diff --git a/packages/cli/test/utils/simulation/tableReporter.ts b/packages/cli/test/utils/crucible/tableReporter.ts similarity index 100% rename from packages/cli/test/utils/simulation/tableReporter.ts rename to packages/cli/test/utils/crucible/tableReporter.ts diff --git a/packages/cli/test/utils/simulation/utils/blobs.ts b/packages/cli/test/utils/crucible/utils/blobs.ts similarity index 100% rename from packages/cli/test/utils/simulation/utils/blobs.ts rename to packages/cli/test/utils/crucible/utils/blobs.ts diff --git a/packages/cli/test/utils/simulation/utils/executionGenesis.ts b/packages/cli/test/utils/crucible/utils/executionGenesis.ts similarity index 100% rename from packages/cli/test/utils/simulation/utils/executionGenesis.ts rename to packages/cli/test/utils/crucible/utils/executionGenesis.ts diff --git a/packages/cli/test/utils/simulation/utils/index.ts b/packages/cli/test/utils/crucible/utils/index.ts similarity index 97% rename from packages/cli/test/utils/simulation/utils/index.ts rename to packages/cli/test/utils/crucible/utils/index.ts index 20fc6d6fbd0..0b6ae1bba1e 100644 --- a/packages/cli/test/utils/simulation/utils/index.ts +++ b/packages/cli/test/utils/crucible/utils/index.ts @@ -9,7 +9,7 @@ import { SIM_ENV_NETWORK_ID, SIM_TESTS_SECONDS_PER_SLOT, } from "../constants.js"; -import {SimulationEnvironment} from "../simulationEnvironment.js"; +import {Simulation} from "../simulation.js"; export const logFilesDir = "test-logs"; @@ -174,7 +174,7 @@ export const replaceIpFromUrl = (url: string, ip: string): string => url.replace export const makeUniqueArray = (arr: T[]): T[] => [...new Set(arr)]; -export const registerProcessHandler = (env: SimulationEnvironment): void => { +export const registerProcessHandler = (env: Simulation): void => { process.on("unhandledRejection", async (reason, promise) => { console.error("Unhandled Rejection at:", promise, "reason:", reason); await env.stop(1, "Unhandled promise rejection"); diff --git a/packages/cli/test/utils/simulation/utils/keys.ts b/packages/cli/test/utils/crucible/utils/keys.ts similarity index 100% rename from packages/cli/test/utils/simulation/utils/keys.ts rename to packages/cli/test/utils/crucible/utils/keys.ts diff --git a/packages/cli/test/utils/simulation/utils/network.ts b/packages/cli/test/utils/crucible/utils/network.ts similarity index 94% rename from packages/cli/test/utils/simulation/utils/network.ts rename to packages/cli/test/utils/crucible/utils/network.ts index fc62d0d6d88..b78087d8f93 100644 --- a/packages/cli/test/utils/simulation/utils/network.ts +++ b/packages/cli/test/utils/crucible/utils/network.ts @@ -3,7 +3,7 @@ import {ApiError} from "@lodestar/api"; import {Slot, allForks} from "@lodestar/types"; import {sleep} from "@lodestar/utils"; import {BeaconClient, BeaconNode, ExecutionClient, ExecutionNode, NodePair} from "../interfaces.js"; -import {SimulationEnvironment} from "../simulationEnvironment.js"; +import {Simulation} from "../simulation.js"; import {SimulationTrackerEvent} from "../simulationTracker.js"; export async function connectAllNodes(nodes: NodePair[]): Promise { @@ -61,7 +61,7 @@ export async function connectNewELNode(newNode: ExecutionNode, nodes: ExecutionN } export async function waitForNodeSync( - env: SimulationEnvironment, + env: Simulation, node: NodePair, options?: {head: string; slot: Slot} ): Promise { @@ -73,7 +73,7 @@ export async function waitForNodeSync( return waitForNodeSyncStatus(env, node); } -export async function waitForNodeSyncStatus(env: SimulationEnvironment, node: NodePair): Promise { +export async function waitForNodeSyncStatus(env: Simulation, node: NodePair): Promise { // eslint-disable-next-line no-constant-condition while (true) { const result = await node.beacon.api.node.getSyncingStatus(); @@ -87,7 +87,7 @@ export async function waitForNodeSyncStatus(env: SimulationEnvironment, node: No } export async function waitForHead( - env: SimulationEnvironment, + env: Simulation, node: NodePair, options: {slot: Slot; head: string; silent?: boolean} ): Promise { @@ -122,7 +122,7 @@ export async function waitForHead( export async function waitForSlot( message: string, - {env, slot, nodes}: {env: SimulationEnvironment; slot: Slot; nodes?: NodePair[]} + {env, slot, nodes}: {env: Simulation; slot: Slot; nodes?: NodePair[]} ): Promise { nodes = nodes ?? env.nodes; diff --git a/packages/cli/test/utils/simulation/utils/paths.ts b/packages/cli/test/utils/crucible/utils/paths.ts similarity index 100% rename from packages/cli/test/utils/simulation/utils/paths.ts rename to packages/cli/test/utils/crucible/utils/paths.ts diff --git a/packages/cli/test/utils/simulation/utils/ports.ts b/packages/cli/test/utils/crucible/utils/ports.ts similarity index 100% rename from packages/cli/test/utils/simulation/utils/ports.ts rename to packages/cli/test/utils/crucible/utils/ports.ts diff --git a/packages/cli/test/utils/simulation/utils/syncing.ts b/packages/cli/test/utils/crucible/utils/syncing.ts similarity index 93% rename from packages/cli/test/utils/simulation/utils/syncing.ts rename to packages/cli/test/utils/crucible/utils/syncing.ts index fdfe3785e62..d56f7d7bb38 100644 --- a/packages/cli/test/utils/simulation/utils/syncing.ts +++ b/packages/cli/test/utils/crucible/utils/syncing.ts @@ -1,11 +1,11 @@ import {ApiError, routes} from "@lodestar/api"; import {Slot} from "@lodestar/types"; import {sleep, toHex} from "@lodestar/utils"; -import type {SimulationEnvironment} from "../simulationEnvironment.js"; +import type {Simulation} from "../simulation.js"; import {BeaconClient, ExecutionClient, NodePair} from "../interfaces.js"; import {connectNewCLNode, connectNewELNode, connectNewNode, waitForHead, waitForSlot} from "./network.js"; -export async function assertRangeSync(env: SimulationEnvironment): Promise { +export async function assertRangeSync(env: Simulation): Promise { const currentHead = await env.nodes[0].beacon.api.beacon.getBlockHeader("head"); ApiError.assert(currentHead); @@ -53,7 +53,7 @@ export async function assertRangeSync(env: SimulationEnvironment): Promise await rangeSync.execution.job.stop(); } -export async function assertCheckpointSync(env: SimulationEnvironment): Promise { +export async function assertCheckpointSync(env: Simulation): Promise { if (env.clock.currentEpoch <= 4) { // First checkpoint finalized is at least 4 epochs await waitForSlot("Waiting for 4th epoch to pass, to get first finalized checkpoint", { @@ -93,7 +93,7 @@ export async function assertCheckpointSync(env: SimulationEnvironment): Promise< await checkpointSync.execution.job.stop(); } -export async function assertUnknownBlockSync(env: SimulationEnvironment): Promise { +export async function assertUnknownBlockSync(env: Simulation): Promise { const currentHead = await env.nodes[0].beacon.api.beacon.getBlockV2("head"); ApiError.assert(currentHead); const currentSidecars = await env.nodes[0].beacon.api.beacon.getBlobSidecars(currentHead.response.data.message.slot); @@ -170,7 +170,7 @@ export async function assertUnknownBlockSync(env: SimulationEnvironment): Promis } export async function waitForNodeSync( - env: SimulationEnvironment, + env: Simulation, node: NodePair, options?: {head: string; slot: Slot} ): Promise { @@ -182,7 +182,7 @@ export async function waitForNodeSync( return waitForNodeSyncStatus(env, node); } -export async function waitForNodeSyncStatus(env: SimulationEnvironment, node: NodePair): Promise { +export async function waitForNodeSyncStatus(env: Simulation, node: NodePair): Promise { // eslint-disable-next-line no-constant-condition while (true) { const result = await node.beacon.api.node.getSyncingStatus(); diff --git a/packages/cli/test/utils/simulation/web3js/blobsEIP4844Transaction.ts b/packages/cli/test/utils/crucible/web3js/blobsEIP4844Transaction.ts similarity index 100% rename from packages/cli/test/utils/simulation/web3js/blobsEIP4844Transaction.ts rename to packages/cli/test/utils/crucible/web3js/blobsEIP4844Transaction.ts diff --git a/packages/cli/test/utils/simulation/web3js/plugins/index.ts b/packages/cli/test/utils/crucible/web3js/plugins/index.ts similarity index 100% rename from packages/cli/test/utils/simulation/web3js/plugins/index.ts rename to packages/cli/test/utils/crucible/web3js/plugins/index.ts diff --git a/packages/cli/test/utils/simulation/web3js/plugins/web3AdminPlugin.ts b/packages/cli/test/utils/crucible/web3js/plugins/web3AdminPlugin.ts similarity index 100% rename from packages/cli/test/utils/simulation/web3js/plugins/web3AdminPlugin.ts rename to packages/cli/test/utils/crucible/web3js/plugins/web3AdminPlugin.ts diff --git a/packages/cli/test/utils/simulation/web3js/plugins/web3ExtendedEthPlugin.ts b/packages/cli/test/utils/crucible/web3js/plugins/web3ExtendedEthPlugin.ts similarity index 100% rename from packages/cli/test/utils/simulation/web3js/plugins/web3ExtendedEthPlugin.ts rename to packages/cli/test/utils/crucible/web3js/plugins/web3ExtendedEthPlugin.ts diff --git a/packages/cli/test/utils/simulation/assertions/matchers.ts b/packages/cli/test/utils/simulation/assertions/matchers.ts deleted file mode 100644 index 931157e49e1..00000000000 --- a/packages/cli/test/utils/simulation/assertions/matchers.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {AssertionMatch, AssertionMatcher} from "../interfaces.js"; - -export const everySlotMatcher: AssertionMatcher = ({slot}) => - slot >= 0 ? AssertionMatch.Capture | AssertionMatch.Assert : AssertionMatch.None; - -export const everyEpochMatcher: AssertionMatcher = ({slot, clock}) => - clock.isLastSlotOfEpoch(slot) ? AssertionMatch.Capture | AssertionMatch.Assert : AssertionMatch.Capture; - -export const neverMatcher: AssertionMatcher = () => AssertionMatch.None; - -export const onceOnSlotMatcher = - (userSlot: number): AssertionMatcher => - ({slot}) => - slot === userSlot ? AssertionMatch.Capture | AssertionMatch.Assert : AssertionMatch.None; - -export const onceOnStartupMatcher = onceOnSlotMatcher(1);