From a8b0025c9013f5c9bfac72dbcfa472eed8b083f5 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 12 May 2023 21:53:17 +0200 Subject: [PATCH 01/18] Add capella support to sim multi-fork tests --- .github/workflows/test-sim.yml | 4 ++-- packages/cli/test/sim/multi_fork.test.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test-sim.yml b/.github/workflows/test-sim.yml index 671536f56ed5..3a3d9dff57ce 100644 --- a/.github/workflows/test-sim.yml +++ b/.github/workflows/test-sim.yml @@ -8,9 +8,9 @@ on: workflow_dispatch: env: - GETH_DOCKER_IMAGE: ethereum/client-go:v1.10.25 + GETH_DOCKER_IMAGE: ethereum/client-go:v1.11.6 LIGHTHOUSE_DOCKER_IMAGE: sigp/lighthouse:latest-amd64-unstable-dev - NETHERMIND_DOCKER_IMAGE: nethermind/nethermind:1.14.5 + NETHERMIND_DOCKER_IMAGE: nethermind/nethermind:1.18.0 jobs: tests-sim: diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 4532b244e757..b021ba328ed2 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -20,9 +20,10 @@ import {mergeAssertion} from "../utils/simulation/assertions/mergeAssertion.js"; const genesisSlotsDelay = 20; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; +const capellaForkEpoch = 6; // Make sure bellatrix started before TTD reach const additionalSlotsForTTD = activePreset.SLOTS_PER_EPOCH - 2; -const runTillEpoch = 6; +const runTillEpoch = 8; const syncWaitEpoch = 2; const runTimeoutMs = @@ -49,6 +50,7 @@ const env = await SimulationEnvironment.initWithDefaults( chainConfig: { ALTAIR_FORK_EPOCH: altairForkEpoch, BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, + CAPELLA_FORK_EPOCH: capellaForkEpoch, GENESIS_DELAY: genesisSlotsDelay, TERMINAL_TOTAL_DIFFICULTY: ttd, }, @@ -79,9 +81,7 @@ env.tracker.register({ await env.start({runTimeoutMs}); await connectAllNodes(env.nodes); -// The `TTD` will be reach around `start of bellatrixForkEpoch + additionalSlotsForMerge` slot -// We wait for the end of that epoch with half more epoch to make sure merge transition is complete -await waitForSlot(env.clock.getLastSlotOfEpoch(bellatrixForkEpoch) + activePreset.SLOTS_PER_EPOCH / 2, env.nodes, { +await waitForSlot(env.clock.getLastSlotOfEpoch(capellaForkEpoch), env.nodes, { silent: true, env, }); From f0374dd3165a5393931640c98dcee142f15d490b Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 12 May 2023 22:19:31 +0200 Subject: [PATCH 02/18] Update the geth opts for newer version --- packages/cli/test/utils/simulation/el_clients/geth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/test/utils/simulation/el_clients/geth.ts b/packages/cli/test/utils/simulation/el_clients/geth.ts index 07d18821666e..4d08a9095049 100644 --- a/packages/cli/test/utils/simulation/el_clients/geth.ts +++ b/packages/cli/test/utils/simulation/el_clients/geth.ts @@ -142,7 +142,7 @@ export const generateGethNode: ELClientGenerator = (opts, runner) // Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail "--verbosity", "5", - ...(mining ? ["--mine"] : []), + ...(mining ? ["--mine", "--miner.etherbase", GENESIS_ACCOUNT] : []), ...(mode == ELStartMode.PreMerge ? ["--nodiscover"] : []), ...clientOptions, ], From c33556dffc616d71f108a0fa0071a927f26daa03 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 12 May 2023 23:42:20 +0200 Subject: [PATCH 03/18] Add shanghai timestamp to el genesis block --- .../utils/simulation/SimulationEnvironment.ts | 40 +++++++++++-------- .../cli/test/utils/simulation/interfaces.ts | 1 + .../test/utils/simulation/utils/el_genesis.ts | 6 ++- .../cli/test/utils/simulation/utils/index.ts | 14 +++++++ 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/packages/cli/test/utils/simulation/SimulationEnvironment.ts b/packages/cli/test/utils/simulation/SimulationEnvironment.ts index 89558ffa6864..0781d6fac997 100644 --- a/packages/cli/test/utils/simulation/SimulationEnvironment.ts +++ b/packages/cli/test/utils/simulation/SimulationEnvironment.ts @@ -33,6 +33,7 @@ import { CLNode, ELClient, ELGeneratorClientOptions, + ELGeneratorGenesisOptions, ELNode, ELStartMode, IRunner, @@ -42,7 +43,13 @@ import { SimulationOptions, } from "./interfaces.js"; import {SimulationTracker} from "./SimulationTracker.js"; -import {getEstimatedTTD, makeUniqueArray, regsiterProcessHandler, replaceIpFromUrl} from "./utils/index.js"; +import { + getEstimatedShanghaiTimestamp, + getEstimatedTTD, + makeUniqueArray, + regsiterProcessHandler, + replaceIpFromUrl, +} from "./utils/index.js"; import {generateLighthouseBeaconNode} from "./cl_clients/lighthouse.js"; import {Runner} from "./runner/index.js"; import {createKeystores} from "./utils/keys.js"; @@ -357,30 +364,31 @@ export class SimulationEnvironment { const mode = options?.mode ?? (this.forkConfig.BELLATRIX_FORK_EPOCH > 0 ? ELStartMode.PreMerge : ELStartMode.PostMerge); - - await writeFile( - elPaths.genesisFilePath, - JSON.stringify( - getGethGenesisBlock(mode, { - ttd: options?.ttd ?? this.forkConfig.TERMINAL_TOTAL_DIFFICULTY, - cliqueSealingPeriod: options?.cliqueSealingPeriod ?? CLIQUE_SEALING_PERIOD, - clientOptions: [], - }) - ) - ); + const genesisOptions: ELGeneratorGenesisOptions = { + ttd: options?.ttd ?? this.forkConfig.TERMINAL_TOTAL_DIFFICULTY, + cliqueSealingPeriod: options?.cliqueSealingPeriod ?? CLIQUE_SEALING_PERIOD, + shanghaiTimestamp: + options?.shanghaiTimestamp ?? + getEstimatedShanghaiTimestamp({ + capellaForkEpoch: this.forkConfig.CAPELLA_FORK_EPOCH, + genesisTime: this.options.genesisTime, + secondsPerSlot: this.forkConfig.SECONDS_PER_SLOT, + }), + clientOptions: options.clientOptions ?? [], + }; const opts: ELGeneratorClientOptions = { + ...genesisOptions, id: elId, paths: elPaths, + mode, nodeIndex: options.nodeIndex, - mode: options?.mode ?? (this.forkConfig.BELLATRIX_FORK_EPOCH > 0 ? ELStartMode.PreMerge : ELStartMode.PostMerge), - ttd: options?.ttd ?? this.forkConfig.TERMINAL_TOTAL_DIFFICULTY, - cliqueSealingPeriod: options?.cliqueSealingPeriod ?? CLIQUE_SEALING_PERIOD, address: this.runner.getNextIp(), mining: options?.mining ?? false, - clientOptions: options.clientOptions ?? [], }; + await writeFile(elPaths.genesisFilePath, JSON.stringify(getGethGenesisBlock(mode, genesisOptions))); + switch (client) { case ELClient.Mock: { return generateMockNode(opts as ELGeneratorClientOptions, this.runner); diff --git a/packages/cli/test/utils/simulation/interfaces.ts b/packages/cli/test/utils/simulation/interfaces.ts index 75189da2d5ad..2a19f91a696f 100644 --- a/packages/cli/test/utils/simulation/interfaces.ts +++ b/packages/cli/test/utils/simulation/interfaces.ts @@ -84,6 +84,7 @@ export interface CLClientGeneratorOptions { export interface ELGeneratorGenesisOptions { ttd: bigint; cliqueSealingPeriod: number; + shanghaiTimestamp: number; clientOptions: ELClientsOptions[E]; } diff --git a/packages/cli/test/utils/simulation/utils/el_genesis.ts b/packages/cli/test/utils/simulation/utils/el_genesis.ts index 30818850e4e2..c05c4995aa2e 100644 --- a/packages/cli/test/utils/simulation/utils/el_genesis.ts +++ b/packages/cli/test/utils/simulation/utils/el_genesis.ts @@ -2,7 +2,7 @@ import {SIM_ENV_CHAIN_ID, SIM_ENV_NETWORK_ID} from "../constants.js"; import {ELGeneratorGenesisOptions, ELStartMode, Eth1GenesisBlock} from "../interfaces.js"; export const getGethGenesisBlock = (mode: ELStartMode, options: ELGeneratorGenesisOptions): Record => { - const {ttd, cliqueSealingPeriod} = options; + const {ttd, cliqueSealingPeriod, shanghaiTimestamp} = options; const genesis = { config: { @@ -20,6 +20,7 @@ export const getGethGenesisBlock = (mode: ELStartMode, options: ELGeneratorGenes muirGlacierBlock: 0, berlinBlock: 0, londonBlock: 0, + shanghaiTimestamp: shanghaiTimestamp, terminalTotalDifficulty: Number(ttd as bigint), clique: {period: cliqueSealingPeriod, epoch: 30000}, }, @@ -60,7 +61,7 @@ export const getNethermindChainSpec = ( mode: ELStartMode, options: ELGeneratorGenesisOptions ): Record => { - const {ttd} = options; + const {ttd, shanghaiTimestamp} = options; const genesis = getGethGenesisBlock(mode, options) as Eth1GenesisBlock; return { @@ -99,6 +100,7 @@ export const getNethermindChainSpec = ( eip3529Transition: "0x0", eip3541Transition: "0x0", terminalTotalDifficulty: Number(ttd as bigint), + shanghaiTimestamp: shanghaiTimestamp, gasLimitBoundDivisor: "0x400", maxCodeSize: "0x6000", maxCodeSizeTransition: "0x0", diff --git a/packages/cli/test/utils/simulation/utils/index.ts b/packages/cli/test/utils/simulation/utils/index.ts index 5468c72371e2..73e7c656aa2e 100644 --- a/packages/cli/test/utils/simulation/utils/index.ts +++ b/packages/cli/test/utils/simulation/utils/index.ts @@ -47,6 +47,20 @@ export const getEstimatedTTD = ({ return BigInt(Math.ceil(secondsTillBellatrix / cliqueSealingPeriod) * ETH_TTD_INCREMENT); }; +export const getEstimatedShanghaiTimestamp = ({ + genesisTime, + secondsPerSlot, + capellaForkEpoch, +}: { + genesisTime: number; + secondsPerSlot: number; + capellaForkEpoch: number; +}): number => { + const secondsTillBellatrix = (capellaForkEpoch - 1) * activePreset.SLOTS_PER_EPOCH * secondsPerSlot; + + return genesisTime + secondsTillBellatrix; +}; + export const squeezeString = (val: string, length: number, sep = "..."): string => { const anchor = Math.floor((length - sep.length) / 2); From dcdff809d94871e1815a479d73845ab58b0fca2a Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Fri, 12 May 2023 23:45:44 +0200 Subject: [PATCH 04/18] Fix nethermind generator --- packages/cli/test/utils/simulation/el_clients/nethermind.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/test/utils/simulation/el_clients/nethermind.ts b/packages/cli/test/utils/simulation/el_clients/nethermind.ts index 94d0dda49fca..62072a93bc34 100644 --- a/packages/cli/test/utils/simulation/el_clients/nethermind.ts +++ b/packages/cli/test/utils/simulation/el_clients/nethermind.ts @@ -15,7 +15,7 @@ export const generateNethermindNode: ELClientGenerator = (o throw Error(`EL ENV must be provided, NETHERMIND_DOCKER_IMAGE: ${process.env.NETHERMIND_DOCKER_IMAGE}`); } - const {id, mode, ttd, address, mining, clientOptions, nodeIndex, cliqueSealingPeriod} = opts; + const {id, mode, ttd, address, mining, clientOptions, nodeIndex, cliqueSealingPeriod, shanghaiTimestamp} = opts; const { el: {httpPort, enginePort, port}, } = getNodePorts(nodeIndex); @@ -46,7 +46,7 @@ export const generateNethermindNode: ELClientGenerator = (o bootstrap: async () => { await writeFile( chainSpecPath, - JSON.stringify(getNethermindChainSpec(mode, {ttd, cliqueSealingPeriod, clientOptions: []})) + JSON.stringify(getNethermindChainSpec(mode, {ttd, cliqueSealingPeriod, shanghaiTimestamp, clientOptions: []})) ); }, cli: { From fbaf8d03d66564a93116f421e0f6d9ffdd324165 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Sat, 13 May 2023 00:14:59 +0200 Subject: [PATCH 05/18] Fix the shanghai time option --- .../cli/test/utils/simulation/SimulationEnvironment.ts | 4 ++-- .../cli/test/utils/simulation/el_clients/nethermind.ts | 4 ++-- packages/cli/test/utils/simulation/interfaces.ts | 2 +- packages/cli/test/utils/simulation/utils/el_genesis.ts | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/cli/test/utils/simulation/SimulationEnvironment.ts b/packages/cli/test/utils/simulation/SimulationEnvironment.ts index 0781d6fac997..6582dc7072f3 100644 --- a/packages/cli/test/utils/simulation/SimulationEnvironment.ts +++ b/packages/cli/test/utils/simulation/SimulationEnvironment.ts @@ -367,8 +367,8 @@ export class SimulationEnvironment { const genesisOptions: ELGeneratorGenesisOptions = { ttd: options?.ttd ?? this.forkConfig.TERMINAL_TOTAL_DIFFICULTY, cliqueSealingPeriod: options?.cliqueSealingPeriod ?? CLIQUE_SEALING_PERIOD, - shanghaiTimestamp: - options?.shanghaiTimestamp ?? + shanghaiTime: + options?.shanghaiTime ?? getEstimatedShanghaiTimestamp({ capellaForkEpoch: this.forkConfig.CAPELLA_FORK_EPOCH, genesisTime: this.options.genesisTime, diff --git a/packages/cli/test/utils/simulation/el_clients/nethermind.ts b/packages/cli/test/utils/simulation/el_clients/nethermind.ts index 62072a93bc34..6d98db0db003 100644 --- a/packages/cli/test/utils/simulation/el_clients/nethermind.ts +++ b/packages/cli/test/utils/simulation/el_clients/nethermind.ts @@ -15,7 +15,7 @@ export const generateNethermindNode: ELClientGenerator = (o throw Error(`EL ENV must be provided, NETHERMIND_DOCKER_IMAGE: ${process.env.NETHERMIND_DOCKER_IMAGE}`); } - const {id, mode, ttd, address, mining, clientOptions, nodeIndex, cliqueSealingPeriod, shanghaiTimestamp} = opts; + const {id, mode, ttd, address, mining, clientOptions, nodeIndex, cliqueSealingPeriod, shanghaiTime} = opts; const { el: {httpPort, enginePort, port}, } = getNodePorts(nodeIndex); @@ -46,7 +46,7 @@ export const generateNethermindNode: ELClientGenerator = (o bootstrap: async () => { await writeFile( chainSpecPath, - JSON.stringify(getNethermindChainSpec(mode, {ttd, cliqueSealingPeriod, shanghaiTimestamp, clientOptions: []})) + JSON.stringify(getNethermindChainSpec(mode, {ttd, cliqueSealingPeriod, shanghaiTime, clientOptions: []})) ); }, cli: { diff --git a/packages/cli/test/utils/simulation/interfaces.ts b/packages/cli/test/utils/simulation/interfaces.ts index 2a19f91a696f..4233fe6ee63f 100644 --- a/packages/cli/test/utils/simulation/interfaces.ts +++ b/packages/cli/test/utils/simulation/interfaces.ts @@ -84,7 +84,7 @@ export interface CLClientGeneratorOptions { export interface ELGeneratorGenesisOptions { ttd: bigint; cliqueSealingPeriod: number; - shanghaiTimestamp: number; + shanghaiTime: number; clientOptions: ELClientsOptions[E]; } diff --git a/packages/cli/test/utils/simulation/utils/el_genesis.ts b/packages/cli/test/utils/simulation/utils/el_genesis.ts index c05c4995aa2e..1e89dbe52022 100644 --- a/packages/cli/test/utils/simulation/utils/el_genesis.ts +++ b/packages/cli/test/utils/simulation/utils/el_genesis.ts @@ -2,7 +2,7 @@ import {SIM_ENV_CHAIN_ID, SIM_ENV_NETWORK_ID} from "../constants.js"; import {ELGeneratorGenesisOptions, ELStartMode, Eth1GenesisBlock} from "../interfaces.js"; export const getGethGenesisBlock = (mode: ELStartMode, options: ELGeneratorGenesisOptions): Record => { - const {ttd, cliqueSealingPeriod, shanghaiTimestamp} = options; + const {ttd, cliqueSealingPeriod, shanghaiTime} = options; const genesis = { config: { @@ -20,7 +20,7 @@ export const getGethGenesisBlock = (mode: ELStartMode, options: ELGeneratorGenes muirGlacierBlock: 0, berlinBlock: 0, londonBlock: 0, - shanghaiTimestamp: shanghaiTimestamp, + shanghaiTime, terminalTotalDifficulty: Number(ttd as bigint), clique: {period: cliqueSealingPeriod, epoch: 30000}, }, @@ -61,7 +61,7 @@ export const getNethermindChainSpec = ( mode: ELStartMode, options: ELGeneratorGenesisOptions ): Record => { - const {ttd, shanghaiTimestamp} = options; + const {ttd, shanghaiTime} = options; const genesis = getGethGenesisBlock(mode, options) as Eth1GenesisBlock; return { @@ -100,7 +100,7 @@ export const getNethermindChainSpec = ( eip3529Transition: "0x0", eip3541Transition: "0x0", terminalTotalDifficulty: Number(ttd as bigint), - shanghaiTimestamp: shanghaiTimestamp, + shanghaiTime, gasLimitBoundDivisor: "0x400", maxCodeSize: "0x6000", maxCodeSizeTransition: "0x0", From 86cf6102dc6bac884b3a422180524d8e628c8df1 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Mon, 15 May 2023 17:37:59 +0200 Subject: [PATCH 06/18] Update shangai time to be relative --- .../cli/test/utils/simulation/SimulationEnvironment.ts | 4 ++-- packages/cli/test/utils/simulation/utils/index.ts | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/cli/test/utils/simulation/SimulationEnvironment.ts b/packages/cli/test/utils/simulation/SimulationEnvironment.ts index 6582dc7072f3..7ce2acebce16 100644 --- a/packages/cli/test/utils/simulation/SimulationEnvironment.ts +++ b/packages/cli/test/utils/simulation/SimulationEnvironment.ts @@ -44,7 +44,7 @@ import { } from "./interfaces.js"; import {SimulationTracker} from "./SimulationTracker.js"; import { - getEstimatedShanghaiTimestamp, + getEstimatedShanghaiTime, getEstimatedTTD, makeUniqueArray, regsiterProcessHandler, @@ -369,7 +369,7 @@ export class SimulationEnvironment { cliqueSealingPeriod: options?.cliqueSealingPeriod ?? CLIQUE_SEALING_PERIOD, shanghaiTime: options?.shanghaiTime ?? - getEstimatedShanghaiTimestamp({ + getEstimatedShanghaiTime({ capellaForkEpoch: this.forkConfig.CAPELLA_FORK_EPOCH, genesisTime: this.options.genesisTime, secondsPerSlot: this.forkConfig.SECONDS_PER_SLOT, diff --git a/packages/cli/test/utils/simulation/utils/index.ts b/packages/cli/test/utils/simulation/utils/index.ts index 73e7c656aa2e..f6222ee9f1de 100644 --- a/packages/cli/test/utils/simulation/utils/index.ts +++ b/packages/cli/test/utils/simulation/utils/index.ts @@ -47,8 +47,7 @@ export const getEstimatedTTD = ({ return BigInt(Math.ceil(secondsTillBellatrix / cliqueSealingPeriod) * ETH_TTD_INCREMENT); }; -export const getEstimatedShanghaiTimestamp = ({ - genesisTime, +export const getEstimatedShanghaiTime = ({ secondsPerSlot, capellaForkEpoch, }: { @@ -56,9 +55,9 @@ export const getEstimatedShanghaiTimestamp = ({ secondsPerSlot: number; capellaForkEpoch: number; }): number => { - const secondsTillBellatrix = (capellaForkEpoch - 1) * activePreset.SLOTS_PER_EPOCH * secondsPerSlot; + const secondsTillCapella = (capellaForkEpoch - 1) * activePreset.SLOTS_PER_EPOCH * secondsPerSlot; - return genesisTime + secondsTillBellatrix; + return secondsTillCapella; }; export const squeezeString = (val: string, length: number, sep = "..."): string => { From 310d322549cb6c26f1aa556b53376031fe821d17 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Mon, 15 May 2023 17:49:43 +0200 Subject: [PATCH 07/18] Update the order of stopping services --- packages/cli/test/utils/simulation/SimulationEnvironment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/test/utils/simulation/SimulationEnvironment.ts b/packages/cli/test/utils/simulation/SimulationEnvironment.ts index 7ce2acebce16..d8f606f02682 100644 --- a/packages/cli/test/utils/simulation/SimulationEnvironment.ts +++ b/packages/cli/test/utils/simulation/SimulationEnvironment.ts @@ -210,12 +210,12 @@ export class SimulationEnvironment { process.removeAllListeners("SIGTERM"); process.removeAllListeners("SIGINT"); console.log(`Simulation environment "${this.options.id}" is stopping: ${message}`); - this.options.controller.abort(); await this.tracker.stop(); await Promise.all(this.nodes.map((node) => node.el.job.stop())); await Promise.all(this.nodes.map((node) => node.cl.job.stop())); await this.externalSigner.stop(); await this.runner.stop(); + this.options.controller.abort(); if (this.tracker.getErrorCount() > 0) { this.tracker.reporter.summary(); From 65e461b04e21002a190df81fba429a458105b5b8 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 16 May 2023 22:13:00 +0200 Subject: [PATCH 08/18] Update the few naming conventions --- .../cli/test/sim/backup_eth_provider.test.ts | 2 +- packages/cli/test/sim/deneb.test.ts | 2 +- packages/cli/test/sim/multi_fork.test.ts | 12 ++++----- .../utils/simulation/SimulationEnvironment.ts | 19 +++++++++----- .../utils/simulation/el_clients/nethermind.ts | 9 ++++--- .../cli/test/utils/simulation/interfaces.ts | 3 ++- .../test/utils/simulation/utils/el_genesis.ts | 9 ++++--- .../cli/test/utils/simulation/utils/index.ts | 26 ++++++++++++------- 8 files changed, 50 insertions(+), 32 deletions(-) diff --git a/packages/cli/test/sim/backup_eth_provider.test.ts b/packages/cli/test/sim/backup_eth_provider.test.ts index c45f6c90f636..1934344d9bb5 100644 --- a/packages/cli/test/sim/backup_eth_provider.test.ts +++ b/packages/cli/test/sim/backup_eth_provider.test.ts @@ -31,7 +31,7 @@ const runTimeoutMs = }) * 1000; const ttd = getEstimatedTTD({ - genesisDelay: genesisSlotsDelay, + genesisDelaySeconds: genesisSlotsDelay, bellatrixForkEpoch: bellatrixForkEpoch, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, cliqueSealingPeriod: CLIQUE_SEALING_PERIOD, diff --git a/packages/cli/test/sim/deneb.test.ts b/packages/cli/test/sim/deneb.test.ts index 6afdacf867ed..a5a394d580e7 100644 --- a/packages/cli/test/sim/deneb.test.ts +++ b/packages/cli/test/sim/deneb.test.ts @@ -28,7 +28,7 @@ const runTimeoutMs = }) * 1000; const ttd = getEstimatedTTD({ - genesisDelay: genesisSlotsDelay, + genesisDelaySeconds: genesisSlotsDelay, bellatrixForkEpoch: bellatrixForkEpoch, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, cliqueSealingPeriod: CLIQUE_SEALING_PERIOD, diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index b021ba328ed2..3966b38f34a9 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -17,18 +17,18 @@ import { import {nodeAssertion} from "../utils/simulation/assertions/nodeAssertion.js"; import {mergeAssertion} from "../utils/simulation/assertions/mergeAssertion.js"; -const genesisSlotsDelay = 20; +const genesisDelaySeconds = 20 * SIM_TESTS_SECONDS_PER_SLOT; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; const capellaForkEpoch = 6; // Make sure bellatrix started before TTD reach -const additionalSlotsForTTD = activePreset.SLOTS_PER_EPOCH - 2; +const additionalSlotsForTTD = 2; const runTillEpoch = 8; const syncWaitEpoch = 2; const runTimeoutMs = getEstimatedTimeInSecForRun({ - genesisSlotDelay: genesisSlotsDelay, + genesisDelaySeconds, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, runTill: runTillEpoch + syncWaitEpoch, // After adding Nethermind its took longer to complete @@ -36,8 +36,8 @@ const runTimeoutMs = }) * 1000; const ttd = getEstimatedTTD({ - genesisDelay: genesisSlotsDelay, - bellatrixForkEpoch: bellatrixForkEpoch, + genesisDelaySeconds, + bellatrixForkEpoch, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, cliqueSealingPeriod: CLIQUE_SEALING_PERIOD, additionalSlots: additionalSlotsForTTD, @@ -51,7 +51,7 @@ const env = await SimulationEnvironment.initWithDefaults( ALTAIR_FORK_EPOCH: altairForkEpoch, BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, CAPELLA_FORK_EPOCH: capellaForkEpoch, - GENESIS_DELAY: genesisSlotsDelay, + GENESIS_DELAY: genesisDelaySeconds, TERMINAL_TOTAL_DIFFICULTY: ttd, }, }, diff --git a/packages/cli/test/utils/simulation/SimulationEnvironment.ts b/packages/cli/test/utils/simulation/SimulationEnvironment.ts index d8f606f02682..a43d65e73262 100644 --- a/packages/cli/test/utils/simulation/SimulationEnvironment.ts +++ b/packages/cli/test/utils/simulation/SimulationEnvironment.ts @@ -82,7 +82,7 @@ export class SimulationEnvironment { this.options = options; this.clock = new EpochClock({ - genesisTime: this.options.genesisTime, + genesisTime: this.options.eth1GenesisTime + this.forkConfig.GENESIS_DELAY, secondsPerSlot: this.forkConfig.SECONDS_PER_SLOT, slotsPerEpoch: activePreset.SLOTS_PER_EPOCH, signal: this.options.controller.signal, @@ -104,11 +104,11 @@ export class SimulationEnvironment { clients: NodePairOptions[] ): Promise { const secondsPerSlot = chainConfig.SECONDS_PER_SLOT ?? SIM_TESTS_SECONDS_PER_SLOT; - const genesisTime = Math.floor(Date.now() / 1000) + chainConfig.GENESIS_DELAY * secondsPerSlot; + const genesisTime = Math.floor(Date.now() / 1000); const ttd = chainConfig.TERMINAL_TOTAL_DIFFICULTY ?? getEstimatedTTD({ - genesisDelay: chainConfig.GENESIS_DELAY, + genesisDelaySeconds: chainConfig.GENESIS_DELAY, bellatrixForkEpoch: chainConfig.BELLATRIX_FORK_EPOCH, secondsPerSlot: secondsPerSlot, cliqueSealingPeriod: CLIQUE_SEALING_PERIOD, @@ -122,12 +122,14 @@ export class SimulationEnvironment { TERMINAL_TOTAL_DIFFICULTY: ttd, DEPOSIT_CHAIN_ID: SIM_ENV_CHAIN_ID, DEPOSIT_NETWORK_ID: SIM_ENV_NETWORK_ID, + SECONDS_PER_ETH1_BLOCK: CLIQUE_SEALING_PERIOD, + ETH1_FOLLOW_DISTANCE: 1, }); const env = new SimulationEnvironment(forkConfig, { logsDir, id, - genesisTime, + eth1GenesisTime: genesisTime, controller: new AbortController(), rootDir: path.join(tmp.dirSync({unsafeCleanup: true, tmpdir: "/tmp", template: "sim-XXXXXX"}).name, id), }); @@ -306,7 +308,7 @@ export class SimulationEnvironment { paths: clPaths, nodeIndex: options.nodeIndex, keys: options?.keys ?? {type: "no-keys"}, - genesisTime: this.options.genesisTime, + genesisTime: this.options.eth1GenesisTime + this.forkConfig.GENESIS_DELAY, engineMock: options?.engineMock ?? false, clientOptions: options?.clientOptions ?? {}, address: "127.0.0.1", @@ -367,12 +369,15 @@ export class SimulationEnvironment { const genesisOptions: ELGeneratorGenesisOptions = { ttd: options?.ttd ?? this.forkConfig.TERMINAL_TOTAL_DIFFICULTY, cliqueSealingPeriod: options?.cliqueSealingPeriod ?? CLIQUE_SEALING_PERIOD, + genesisTime: options?.genesisTime ?? this.options.eth1GenesisTime, shanghaiTime: options?.shanghaiTime ?? getEstimatedShanghaiTime({ + genesisDelaySeconds: this.forkConfig.GENESIS_DELAY, capellaForkEpoch: this.forkConfig.CAPELLA_FORK_EPOCH, - genesisTime: this.options.genesisTime, + eth1GenesisTime: this.options.eth1GenesisTime, secondsPerSlot: this.forkConfig.SECONDS_PER_SLOT, + additionalSlots: 0, }), clientOptions: options.clientOptions ?? [], }; @@ -417,7 +422,7 @@ export class SimulationEnvironment { } const genesisState = nodeUtils.initDevState(this.forkConfig, this.keysCount, { - genesisTime: this.options.genesisTime, + genesisTime: this.options.eth1GenesisTime + this.forkConfig.GENESIS_DELAY, eth1BlockHash: fromHexString(eth1Genesis.hash), }).state; diff --git a/packages/cli/test/utils/simulation/el_clients/nethermind.ts b/packages/cli/test/utils/simulation/el_clients/nethermind.ts index 6d98db0db003..8da5b2ebbbfd 100644 --- a/packages/cli/test/utils/simulation/el_clients/nethermind.ts +++ b/packages/cli/test/utils/simulation/el_clients/nethermind.ts @@ -15,7 +15,8 @@ export const generateNethermindNode: ELClientGenerator = (o throw Error(`EL ENV must be provided, NETHERMIND_DOCKER_IMAGE: ${process.env.NETHERMIND_DOCKER_IMAGE}`); } - const {id, mode, ttd, address, mining, clientOptions, nodeIndex, cliqueSealingPeriod, shanghaiTime} = opts; + const {id, mode, ttd, address, mining, clientOptions, nodeIndex, cliqueSealingPeriod, shanghaiTime, genesisTime} = + opts; const { el: {httpPort, enginePort, port}, } = getNodePorts(nodeIndex); @@ -46,7 +47,9 @@ export const generateNethermindNode: ELClientGenerator = (o bootstrap: async () => { await writeFile( chainSpecPath, - JSON.stringify(getNethermindChainSpec(mode, {ttd, cliqueSealingPeriod, shanghaiTime, clientOptions: []})) + JSON.stringify( + getNethermindChainSpec(mode, {ttd, cliqueSealingPeriod, shanghaiTime, genesisTime, clientOptions: []}) + ) ); }, cli: { @@ -86,7 +89,7 @@ export const generateNethermindNode: ELClientGenerator = (o String(port as number), // OFF|TRACE|DEBUG|INFO|WARN|ERROR "--log", - "INFO", + "DEBUG", "--config", "none", ...(mining ? ["--Init.IsMining", "true", "--Mining.Enabled", "true"] : []), diff --git a/packages/cli/test/utils/simulation/interfaces.ts b/packages/cli/test/utils/simulation/interfaces.ts index 4233fe6ee63f..18ed9a6fc070 100644 --- a/packages/cli/test/utils/simulation/interfaces.ts +++ b/packages/cli/test/utils/simulation/interfaces.ts @@ -24,7 +24,7 @@ export type SimulationOptions = { logsDir: string; rootDir: string; controller: AbortController; - genesisTime: number; + eth1GenesisTime: number; }; export enum CLClient { @@ -85,6 +85,7 @@ export interface ELGeneratorGenesisOptions { ttd: bigint; cliqueSealingPeriod: number; shanghaiTime: number; + genesisTime: number; clientOptions: ELClientsOptions[E]; } diff --git a/packages/cli/test/utils/simulation/utils/el_genesis.ts b/packages/cli/test/utils/simulation/utils/el_genesis.ts index 1e89dbe52022..ed4ea355a27e 100644 --- a/packages/cli/test/utils/simulation/utils/el_genesis.ts +++ b/packages/cli/test/utils/simulation/utils/el_genesis.ts @@ -2,7 +2,7 @@ import {SIM_ENV_CHAIN_ID, SIM_ENV_NETWORK_ID} from "../constants.js"; import {ELGeneratorGenesisOptions, ELStartMode, Eth1GenesisBlock} from "../interfaces.js"; export const getGethGenesisBlock = (mode: ELStartMode, options: ELGeneratorGenesisOptions): Record => { - const {ttd, cliqueSealingPeriod, shanghaiTime} = options; + const {ttd, cliqueSealingPeriod, shanghaiTime, genesisTime} = options; const genesis = { config: { @@ -25,7 +25,7 @@ export const getGethGenesisBlock = (mode: ELStartMode, options: ELGeneratorGenes clique: {period: cliqueSealingPeriod, epoch: 30000}, }, nonce: "0x0", - timestamp: "0x6159af19", + timestamp: `0x${genesisTime.toString(16)}`, extraData: "0x0000000000000000000000000000000000000000000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", gasLimit: "0x1c9c380", @@ -100,12 +100,15 @@ export const getNethermindChainSpec = ( eip3529Transition: "0x0", eip3541Transition: "0x0", terminalTotalDifficulty: Number(ttd as bigint), - shanghaiTime, gasLimitBoundDivisor: "0x400", maxCodeSize: "0x6000", maxCodeSizeTransition: "0x0", maximumExtraDataSize: "0xfff", minGasLimit: "0x0", + eip4895TransitionTimestamp: `0x${shanghaiTime.toString(16)}`, + eip3855TransitionTimestamp: `0x${shanghaiTime.toString(16)}`, + eip3651TransitionTimestamp: `0x${shanghaiTime.toString(16)}`, + eip3860TransitionTimestamp: `0x${shanghaiTime.toString(16)}`, }, accounts: genesis.alloc, genesis: genesis, diff --git a/packages/cli/test/utils/simulation/utils/index.ts b/packages/cli/test/utils/simulation/utils/index.ts index f6222ee9f1de..2e8bb4183049 100644 --- a/packages/cli/test/utils/simulation/utils/index.ts +++ b/packages/cli/test/utils/simulation/utils/index.ts @@ -1,6 +1,6 @@ /* eslint-disable no-console */ import {activePreset} from "@lodestar/params"; -import {Epoch, Slot} from "@lodestar/types"; +import {Epoch} from "@lodestar/types"; import {ETH_TTD_INCREMENT} from "../constants.js"; import {SimulationEnvironment} from "../SimulationEnvironment.js"; @@ -11,36 +11,37 @@ export const avg = (arr: number[]): number => { }; export const getEstimatedTimeInSecForRun = ({ - genesisSlotDelay, + genesisDelaySeconds, runTill, secondsPerSlot, graceExtraTimeFraction, }: { - genesisSlotDelay: Slot; + genesisDelaySeconds: number; runTill: Epoch; secondsPerSlot: number; graceExtraTimeFraction: number; }): number => { - const durationSec = secondsPerSlot * activePreset.SLOTS_PER_EPOCH * runTill + secondsPerSlot * genesisSlotDelay; + const durationSec = secondsPerSlot * activePreset.SLOTS_PER_EPOCH * runTill + genesisDelaySeconds; return Math.round(durationSec + durationSec * graceExtraTimeFraction); }; export const getEstimatedTTD = ({ - genesisDelay, + genesisDelaySeconds, cliqueSealingPeriod, secondsPerSlot, additionalSlots, bellatrixForkEpoch, }: { - genesisDelay: number; + genesisDelaySeconds: number; cliqueSealingPeriod: number; additionalSlots: number; secondsPerSlot: number; bellatrixForkEpoch: number; }): bigint => { + // Need to investigate why TTD always remain 1 epoch ahead, for now just subtract 1 epoch const secondsTillBellatrix = - genesisDelay * secondsPerSlot + + genesisDelaySeconds + (bellatrixForkEpoch - 1) * activePreset.SLOTS_PER_EPOCH * secondsPerSlot + additionalSlots * secondsPerSlot; @@ -48,16 +49,21 @@ export const getEstimatedTTD = ({ }; export const getEstimatedShanghaiTime = ({ + genesisDelaySeconds, + eth1GenesisTime, secondsPerSlot, capellaForkEpoch, + additionalSlots, }: { - genesisTime: number; + genesisDelaySeconds: number; + eth1GenesisTime: number; secondsPerSlot: number; capellaForkEpoch: number; + additionalSlots: number; }): number => { - const secondsTillCapella = (capellaForkEpoch - 1) * activePreset.SLOTS_PER_EPOCH * secondsPerSlot; + const secondsTillCapella = capellaForkEpoch * activePreset.SLOTS_PER_EPOCH * secondsPerSlot; - return secondsTillCapella; + return eth1GenesisTime + genesisDelaySeconds + secondsTillCapella + additionalSlots * secondsPerSlot; }; export const squeezeString = (val: string, length: number, sep = "..."): string => { From a246077d4f5f741e15346edf8d17d35b4ebe57f0 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 16 May 2023 22:23:18 +0200 Subject: [PATCH 09/18] Update the sim tests variable names --- packages/cli/test/sim/backup_eth_provider.test.ts | 8 ++++---- packages/cli/test/sim/deneb.test.ts | 8 ++++---- packages/cli/test/sim/endpoints.test.ts | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/cli/test/sim/backup_eth_provider.test.ts b/packages/cli/test/sim/backup_eth_provider.test.ts index 1934344d9bb5..9ea8aa6cdd69 100644 --- a/packages/cli/test/sim/backup_eth_provider.test.ts +++ b/packages/cli/test/sim/backup_eth_provider.test.ts @@ -13,7 +13,7 @@ import { } from "../utils/simulation/utils/index.js"; import {connectAllNodes, waitForSlot} from "../utils/simulation/utils/network.js"; -const genesisSlotsDelay = 20; +const genesisDelaySeconds = 20 * SIM_TESTS_SECONDS_PER_SLOT; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; // Make sure bellatrix started before TTD reach @@ -23,7 +23,7 @@ const syncWaitEpoch = 2; const runTimeoutMs = getEstimatedTimeInSecForRun({ - genesisSlotDelay: genesisSlotsDelay, + genesisDelaySeconds, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, runTill: runTillEpoch + syncWaitEpoch, // After adding Nethermind its took longer to complete @@ -31,7 +31,7 @@ const runTimeoutMs = }) * 1000; const ttd = getEstimatedTTD({ - genesisDelaySeconds: genesisSlotsDelay, + genesisDelaySeconds, bellatrixForkEpoch: bellatrixForkEpoch, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, cliqueSealingPeriod: CLIQUE_SEALING_PERIOD, @@ -45,7 +45,7 @@ const env = await SimulationEnvironment.initWithDefaults( chainConfig: { ALTAIR_FORK_EPOCH: altairForkEpoch, BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, - GENESIS_DELAY: genesisSlotsDelay, + GENESIS_DELAY: genesisDelaySeconds, TERMINAL_TOTAL_DIFFICULTY: ttd, }, }, diff --git a/packages/cli/test/sim/deneb.test.ts b/packages/cli/test/sim/deneb.test.ts index a5a394d580e7..598508015ae3 100644 --- a/packages/cli/test/sim/deneb.test.ts +++ b/packages/cli/test/sim/deneb.test.ts @@ -10,7 +10,7 @@ import {SimulationEnvironment} from "../utils/simulation/SimulationEnvironment.j import {getEstimatedTimeInSecForRun, getEstimatedTTD, logFilesDir} from "../utils/simulation/utils/index.js"; import {connectAllNodes, connectNewNode, waitForNodeSync, waitForSlot} from "../utils/simulation/utils/network.js"; -const genesisSlotsDelay = 20; +const genesisDelaySeconds = 20 * SIM_TESTS_SECONDS_PER_SLOT; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; // Make sure bellatrix started before TTD reach @@ -20,7 +20,7 @@ const syncWaitEpoch = 2; const runTimeoutMs = getEstimatedTimeInSecForRun({ - genesisSlotDelay: genesisSlotsDelay, + genesisDelaySeconds, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, runTill: runTillEpoch + syncWaitEpoch, // After adding Nethermind its took longer to complete @@ -28,7 +28,7 @@ const runTimeoutMs = }) * 1000; const ttd = getEstimatedTTD({ - genesisDelaySeconds: genesisSlotsDelay, + genesisDelaySeconds, bellatrixForkEpoch: bellatrixForkEpoch, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, cliqueSealingPeriod: CLIQUE_SEALING_PERIOD, @@ -42,7 +42,7 @@ const env = await SimulationEnvironment.initWithDefaults( chainConfig: { ALTAIR_FORK_EPOCH: altairForkEpoch, BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, - GENESIS_DELAY: genesisSlotsDelay, + GENESIS_DELAY: genesisDelaySeconds, TERMINAL_TOTAL_DIFFICULTY: ttd, }, }, diff --git a/packages/cli/test/sim/endpoints.test.ts b/packages/cli/test/sim/endpoints.test.ts index 9fa6caa915fa..3fe294f2324b 100644 --- a/packages/cli/test/sim/endpoints.test.ts +++ b/packages/cli/test/sim/endpoints.test.ts @@ -10,13 +10,13 @@ import {getEstimatedTimeInSecForRun, logFilesDir} from "../utils/simulation/util import {waitForSlot} from "../utils/simulation/utils/network.js"; import {SIM_TESTS_SECONDS_PER_SLOT} from "../utils/simulation/constants.js"; -const genesisSlotsDelay = 10; +const genesisDelaySeconds = 10 * SIM_TESTS_SECONDS_PER_SLOT; const altairForkEpoch = 2; const bellatrixForkEpoch = 4; const validatorCount = 2; const runTimeoutMs = getEstimatedTimeInSecForRun({ - genesisSlotDelay: genesisSlotsDelay, + genesisDelaySeconds, secondsPerSlot: SIM_TESTS_SECONDS_PER_SLOT, runTill: 2, // After adding Nethermind its took longer to complete @@ -30,7 +30,7 @@ const env = await SimulationEnvironment.initWithDefaults( chainConfig: { ALTAIR_FORK_EPOCH: altairForkEpoch, BELLATRIX_FORK_EPOCH: bellatrixForkEpoch, - GENESIS_DELAY: genesisSlotsDelay, + GENESIS_DELAY: genesisDelaySeconds, }, }, [ From 709b317fc54bd532d284f0c0258def93a2cbea32 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Tue, 16 May 2023 23:55:48 +0200 Subject: [PATCH 10/18] Update the multi_fork tests --- packages/cli/test/sim/multi_fork.test.ts | 31 ++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 3966b38f34a9..1cfa0f75995e 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; -import {activePreset} from "@lodestar/params"; import {sleep, toHexString} from "@lodestar/utils"; import {ApiError} from "@lodestar/api"; import {CLIQUE_SEALING_PERIOD, SIM_TESTS_SECONDS_PER_SLOT} from "../utils/simulation/constants.js"; @@ -81,7 +80,35 @@ env.tracker.register({ await env.start({runTimeoutMs}); await connectAllNodes(env.nodes); -await waitForSlot(env.clock.getLastSlotOfEpoch(capellaForkEpoch), env.nodes, { +for (const fork of env.forkConfig.forksAscendingEpochOrder) { + env.tracker.register({ + id: `fork-${fork.name}`, + assert: async ({nodes, slot}) => { + const errors: string[] = []; + for (const node of nodes) { + const res = await node.cl.api.debug.getStateV2("head"); + ApiError.assert(res); + if (res.response.data.fork.currentVersion !== env.forkConfig.getForkInfo(slot).version) { + errors.push( + `Node is not on correct fork. ${JSON.stringify({ + id: node.cl.id, + slot, + expectedFork: env.forkConfig.getForkInfo(slot).version, + currentFork: res.response.data.fork.currentVersion, + })}` + ); + } + } + + return errors; + }, + match: ({slot}) => { + return slot === env.clock.getFirstSlotOfEpoch(fork.epoch) ? {match: true, remove: true} : false; + }, + }); +} + +await waitForSlot(env.clock.getLastSlotOfEpoch(env.forkConfig.forksDescendingEpochOrder[0].epoch + 1), env.nodes, { silent: true, env, }); From 0b08b5aaab03d5c57fd0e02c488c95ff4c339353 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 17 May 2023 00:12:20 +0200 Subject: [PATCH 11/18] Update the fork version comparision --- packages/cli/test/sim/multi_fork.test.ts | 14 ++++++++++---- packages/cli/test/utils/simulation/utils/index.ts | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 1cfa0f75995e..70871bbe0522 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -5,7 +5,12 @@ import {ApiError} from "@lodestar/api"; import {CLIQUE_SEALING_PERIOD, SIM_TESTS_SECONDS_PER_SLOT} from "../utils/simulation/constants.js"; import {CLClient, ELClient} from "../utils/simulation/interfaces.js"; import {SimulationEnvironment} from "../utils/simulation/SimulationEnvironment.js"; -import {getEstimatedTimeInSecForRun, getEstimatedTTD, logFilesDir} from "../utils/simulation/utils/index.js"; +import { + arrayEquals, + getEstimatedTimeInSecForRun, + getEstimatedTTD, + logFilesDir, +} from "../utils/simulation/utils/index.js"; import { connectAllNodes, connectNewNode, @@ -88,13 +93,14 @@ for (const fork of env.forkConfig.forksAscendingEpochOrder) { for (const node of nodes) { const res = await node.cl.api.debug.getStateV2("head"); ApiError.assert(res); - if (res.response.data.fork.currentVersion !== env.forkConfig.getForkInfo(slot).version) { + if (!arrayEquals(res.response.data.fork.currentVersion, env.forkConfig.getForkInfo(slot).version)) { errors.push( `Node is not on correct fork. ${JSON.stringify({ id: node.cl.id, slot, - expectedFork: env.forkConfig.getForkInfo(slot).version, - currentFork: res.response.data.fork.currentVersion, + fork: fork.name, + expectedForkVersion: toHexString(env.forkConfig.getForkInfo(slot).version), + currentForkVersion: toHexString(res.response.data.fork.currentVersion), })}` ); } diff --git a/packages/cli/test/utils/simulation/utils/index.ts b/packages/cli/test/utils/simulation/utils/index.ts index 2e8bb4183049..159aaf1f7b7b 100644 --- a/packages/cli/test/utils/simulation/utils/index.ts +++ b/packages/cli/test/utils/simulation/utils/index.ts @@ -72,7 +72,7 @@ export const squeezeString = (val: string, length: number, sep = "..."): string return `${val.slice(0, anchor)}${sep}${val.slice(-anchor)}`; }; -export function arrayEquals(a: unknown[], b: unknown[]): boolean { +export function arrayEquals(a: unknown[] | Uint8Array, b: unknown[] | Uint8Array): boolean { return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((val, index) => val === b[index]); } From 5ab1a650c83f28477b9ace2d9789c4ef7cbee2ee Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 17 May 2023 00:28:43 +0200 Subject: [PATCH 12/18] Update the version check --- packages/cli/test/sim/multi_fork.test.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 70871bbe0522..6f7ce4565e01 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -5,12 +5,7 @@ import {ApiError} from "@lodestar/api"; import {CLIQUE_SEALING_PERIOD, SIM_TESTS_SECONDS_PER_SLOT} from "../utils/simulation/constants.js"; import {CLClient, ELClient} from "../utils/simulation/interfaces.js"; import {SimulationEnvironment} from "../utils/simulation/SimulationEnvironment.js"; -import { - arrayEquals, - getEstimatedTimeInSecForRun, - getEstimatedTTD, - logFilesDir, -} from "../utils/simulation/utils/index.js"; +import {getEstimatedTimeInSecForRun, getEstimatedTTD, logFilesDir} from "../utils/simulation/utils/index.js"; import { connectAllNodes, connectNewNode, @@ -93,14 +88,17 @@ for (const fork of env.forkConfig.forksAscendingEpochOrder) { for (const node of nodes) { const res = await node.cl.api.debug.getStateV2("head"); ApiError.assert(res); - if (!arrayEquals(res.response.data.fork.currentVersion, env.forkConfig.getForkInfo(slot).version)) { + const expectedForkVersion = toHexString(env.forkConfig.getForkInfo(slot).version); + const currentForkVersion = toHexString(res.response.data.fork.currentVersion); + + if (expectedForkVersion !== currentForkVersion) { errors.push( `Node is not on correct fork. ${JSON.stringify({ id: node.cl.id, slot, fork: fork.name, - expectedForkVersion: toHexString(env.forkConfig.getForkInfo(slot).version), - currentForkVersion: toHexString(res.response.data.fork.currentVersion), + expectedForkVersion, + currentForkVersion, })}` ); } From 7b01d62451b75e27cfc89ba788b06c4837e4e5ff Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 17 May 2023 00:55:30 +0200 Subject: [PATCH 13/18] Add the wait log --- packages/cli/test/sim/multi_fork.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 6f7ce4565e01..4d1628506ac4 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -113,7 +113,6 @@ for (const fork of env.forkConfig.forksAscendingEpochOrder) { } await waitForSlot(env.clock.getLastSlotOfEpoch(env.forkConfig.forksDescendingEpochOrder[0].epoch + 1), env.nodes, { - silent: true, env, }); From 6b0e34488ccb92916ac63efd1c3cfc854a92355d Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 17 May 2023 01:09:17 +0200 Subject: [PATCH 14/18] Update the last fork check --- packages/cli/test/sim/multi_fork.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 4d1628506ac4..b27612b3dfa0 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -80,7 +80,11 @@ env.tracker.register({ await env.start({runTimeoutMs}); await connectAllNodes(env.nodes); +const lastForkEpoch = 0; for (const fork of env.forkConfig.forksAscendingEpochOrder) { + if (!Number.isInteger(fork.epoch)) continue; + + const lastForkEpoch = fork.epoch; env.tracker.register({ id: `fork-${fork.name}`, assert: async ({nodes, slot}) => { @@ -112,7 +116,7 @@ for (const fork of env.forkConfig.forksAscendingEpochOrder) { }); } -await waitForSlot(env.clock.getLastSlotOfEpoch(env.forkConfig.forksDescendingEpochOrder[0].epoch + 1), env.nodes, { +await waitForSlot(env.clock.getLastSlotOfEpoch(lastForkEpoch + 1), env.nodes, { env, }); From 9b8697f0d8f44ab4ff86103f6927a615d7f013be Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 17 May 2023 01:23:48 +0200 Subject: [PATCH 15/18] Fix lint error --- packages/cli/test/sim/multi_fork.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index b27612b3dfa0..b503425ba577 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -80,11 +80,11 @@ env.tracker.register({ await env.start({runTimeoutMs}); await connectAllNodes(env.nodes); -const lastForkEpoch = 0; +let lastForkEpoch = 0; for (const fork of env.forkConfig.forksAscendingEpochOrder) { if (!Number.isInteger(fork.epoch)) continue; - const lastForkEpoch = fork.epoch; + lastForkEpoch = fork.epoch; env.tracker.register({ id: `fork-${fork.name}`, assert: async ({nodes, slot}) => { From 47945a7ae4627c49aafc259d9767b135572cc2b8 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 17 May 2023 12:15:34 +0200 Subject: [PATCH 16/18] Move the fork assertion to seperate file --- packages/cli/test/sim/multi_fork.test.ts | 32 +--------------- .../simulation/assertions/forkAssertion.ts | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 30 deletions(-) create mode 100644 packages/cli/test/utils/simulation/assertions/forkAssertion.ts diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index b503425ba577..7a882732fb84 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -15,6 +15,7 @@ import { } 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"; const genesisDelaySeconds = 20 * SIM_TESTS_SECONDS_PER_SLOT; const altairForkEpoch = 2; @@ -83,37 +84,8 @@ await connectAllNodes(env.nodes); let lastForkEpoch = 0; for (const fork of env.forkConfig.forksAscendingEpochOrder) { if (!Number.isInteger(fork.epoch)) continue; - lastForkEpoch = fork.epoch; - env.tracker.register({ - id: `fork-${fork.name}`, - assert: async ({nodes, slot}) => { - const errors: string[] = []; - for (const node of nodes) { - const res = await node.cl.api.debug.getStateV2("head"); - ApiError.assert(res); - const expectedForkVersion = toHexString(env.forkConfig.getForkInfo(slot).version); - const currentForkVersion = toHexString(res.response.data.fork.currentVersion); - - if (expectedForkVersion !== currentForkVersion) { - errors.push( - `Node is not on correct fork. ${JSON.stringify({ - id: node.cl.id, - slot, - fork: fork.name, - expectedForkVersion, - currentForkVersion, - })}` - ); - } - } - - return errors; - }, - match: ({slot}) => { - return slot === env.clock.getFirstSlotOfEpoch(fork.epoch) ? {match: true, remove: true} : false; - }, - }); + env.tracker.register(createForkAssertion(fork.name, fork.epoch)); } await waitForSlot(env.clock.getLastSlotOfEpoch(lastForkEpoch + 1), env.nodes, { diff --git a/packages/cli/test/utils/simulation/assertions/forkAssertion.ts b/packages/cli/test/utils/simulation/assertions/forkAssertion.ts new file mode 100644 index 000000000000..c24c1874fcd6 --- /dev/null +++ b/packages/cli/test/utils/simulation/assertions/forkAssertion.ts @@ -0,0 +1,37 @@ +import {ApiError} from "@lodestar/api"; +import {ForkName} from "@lodestar/params"; +import {Epoch} from "@lodestar/types"; +import {toHexString} from "@lodestar/utils"; +import {SimulationAssertion} from "../interfaces.js"; + +export function createForkAssertion(fork: ForkName, epoch: Epoch): SimulationAssertion { + return { + id: `fork-${fork}`, + match: ({slot, clock}) => { + return slot === clock.getFirstSlotOfEpoch(epoch) ? {match: true, remove: true} : false; + }, + assert: async ({nodes, slot, forkConfig}) => { + const errors: string[] = []; + for (const node of nodes) { + const res = await node.cl.api.debug.getStateV2("head"); + ApiError.assert(res); + const expectedForkVersion = toHexString(forkConfig.getForkInfo(slot).version); + const currentForkVersion = toHexString(res.response.data.fork.currentVersion); + + if (expectedForkVersion !== currentForkVersion) { + errors.push( + `Node is not on correct fork. ${JSON.stringify({ + id: node.cl.id, + slot, + fork, + expectedForkVersion, + currentForkVersion, + })}` + ); + } + } + + return errors; + }, + }; +} From 7ef9c28f94216cacdc7d5dfd19ac79aa84cef881 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 17 May 2023 12:19:30 +0200 Subject: [PATCH 17/18] Correct spelling --- packages/cli/test/utils/simulation/SimulationEnvironment.ts | 4 ++-- packages/cli/test/utils/simulation/utils/index.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/cli/test/utils/simulation/SimulationEnvironment.ts b/packages/cli/test/utils/simulation/SimulationEnvironment.ts index a43d65e73262..8711ed4ba255 100644 --- a/packages/cli/test/utils/simulation/SimulationEnvironment.ts +++ b/packages/cli/test/utils/simulation/SimulationEnvironment.ts @@ -47,7 +47,7 @@ import { getEstimatedShanghaiTime, getEstimatedTTD, makeUniqueArray, - regsiterProcessHandler, + registerProcessHandler, replaceIpFromUrl, } from "./utils/index.js"; import {generateLighthouseBeaconNode} from "./cl_clients/lighthouse.js"; @@ -166,7 +166,7 @@ export class SimulationEnvironment { }, msToGenesis); try { - regsiterProcessHandler(this); + registerProcessHandler(this); if (!fs.existsSync(this.options.rootDir)) { await mkdir(this.options.rootDir); } diff --git a/packages/cli/test/utils/simulation/utils/index.ts b/packages/cli/test/utils/simulation/utils/index.ts index 159aaf1f7b7b..f765ec08789d 100644 --- a/packages/cli/test/utils/simulation/utils/index.ts +++ b/packages/cli/test/utils/simulation/utils/index.ts @@ -96,7 +96,7 @@ export const replaceIpFromUrl = (url: string, ip: string): string => url.replace export const makeUniqueArray = (arr: T[]): T[] => [...new Set(arr)]; -export const regsiterProcessHandler = (env: SimulationEnvironment): void => { +export const registerProcessHandler = (env: SimulationEnvironment): void => { process.on("unhandledRejection", async (reason, promise) => { console.error("Unhandled Rejection at:", promise, "reason:", reason); await env.stop(1, "Unhandled promise rejection"); From a78c493abae0c4af56c6265f4ff2849d7d9ceec1 Mon Sep 17 00:00:00 2001 From: Nazar Hussain Date: Wed, 17 May 2023 15:32:35 +0200 Subject: [PATCH 18/18] Update the code comment --- packages/cli/test/sim/multi_fork.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index 7a882732fb84..326e357d3abb 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -82,6 +82,8 @@ await env.start({runTimeoutMs}); await connectAllNodes(env.nodes); let lastForkEpoch = 0; +// Go through every fork and check which one is active and register assertion for it +// This will make sure this test would identify if we add new fork or activate one of the existing ones for (const fork of env.forkConfig.forksAscendingEpochOrder) { if (!Number.isInteger(fork.epoch)) continue; lastForkEpoch = fork.epoch;