diff --git a/packages/fp/tsconfig.tsbuildinfo b/packages/fp/tsconfig.tsbuildinfo index 2c8c11c9..ec78aa7c 100644 --- a/packages/fp/tsconfig.tsbuildinfo +++ b/packages/fp/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/TaskEither.ts","./src/index.ts"],"version":"5.7.3"} \ No newline at end of file +{"root":["./src/taskeither.ts","./src/index.ts"],"version":"5.7.3"} \ No newline at end of file diff --git a/packages/services/package.json b/packages/services/package.json index da20c68e..ff500258 100644 --- a/packages/services/package.json +++ b/packages/services/package.json @@ -19,6 +19,7 @@ "@devnet/utils": "workspace:*", "@fastify/swagger": "^9.4.2", "@fastify/swagger-ui": "^5.2.1", + "@iarna/toml": "^2.2.5", "@oclif/core": "^4.0.37", "@oclif/plugin-help": "^6.2.19", "@types/node": "^22.10.5", diff --git a/packages/services/src/devnet-service.ts b/packages/services/src/devnet-service.ts index eb338a6e..abd71d55 100644 --- a/packages/services/src/devnet-service.ts +++ b/packages/services/src/devnet-service.ts @@ -22,6 +22,7 @@ import { } from "node:fs/promises"; import path from "node:path"; import * as YAML from "yaml"; +import * as toml from "@iarna/toml"; import { DevnetServiceArtifact } from "./devnet-service-artifact.js"; import { serviceConfigs } from "./embedded/index.js"; @@ -192,6 +193,10 @@ export class DevNetService { return JSON.parse(await this.readFile(relativePath)); } + public async readToml(relativePath: string) { + return toml.parse(await this.readFile(relativePath)); + } + public async readYaml(relativePath: string) { return YAML.parse(await this.readFile(relativePath), { intAsBigInt: true }); } @@ -226,6 +231,10 @@ export class DevNetService { return await this.writeFile(relativePath, json); } + public async writeToml(relativePath: string, fileContent: toml.JsonMap) { + return await this.writeFile(relativePath, toml.stringify(fileContent)); + } + public async writeYaml(relativePath: string, fileContent: unknown) { return await this.writeFile(relativePath, YAML.stringify(fileContent)); } diff --git a/packages/services/src/embedded/csm-prover-tool.ts b/packages/services/src/embedded/csm-prover-tool.ts index 03dde7b2..06a98842 100644 --- a/packages/services/src/embedded/csm-prover-tool.ts +++ b/packages/services/src/embedded/csm-prover-tool.ts @@ -3,7 +3,7 @@ import { DevnetServiceConfig } from "../devnet-service-config.js"; export const csmProverTool = new DevnetServiceConfig({ repository: { url: "git@github.com:lidofinance/csm-prover-tool.git", - branch: "feat/support-fusaka", + branch: "develop", }, workspace: "workspaces/csm-prover-tool", name: "csmProverTool" as const, diff --git a/packages/services/src/embedded/genesis-generator.ts b/packages/services/src/embedded/genesis-generator.ts new file mode 100644 index 00000000..3a7c7324 --- /dev/null +++ b/packages/services/src/embedded/genesis-generator.ts @@ -0,0 +1,13 @@ +import { DevnetServiceConfig } from "../devnet-service-config.js"; + +export const ethGenenisGenerator = new DevnetServiceConfig({ + repository: { + url: "git@github.com:AlexandrMov/ethereum-genesis-generator.git", + branch: "master", + }, + workspace: "workspaces/genesis-generator", + name: "ethGenenisGenerator" as const, + constants: {}, + labels: {}, + getters: {}, +}); diff --git a/packages/services/src/embedded/index.ts b/packages/services/src/embedded/index.ts index b65e5998..f11fb14e 100644 --- a/packages/services/src/embedded/index.ts +++ b/packages/services/src/embedded/index.ts @@ -6,6 +6,7 @@ import { csmProverTool } from "./csm-prover-tool.js"; import { dataBus } from "./data-bus.js"; import { dockerRegistry } from "./docker-registry.js"; import { dsmBots } from "./dsm-bots.js"; +import { ethGenenisGenerator } from "./genesis-generator.js"; import { kapi } from "./kapi.js"; import { kubo } from "./kubo.js"; import { kurtosis } from "./kurtosis.js" @@ -19,6 +20,7 @@ import { voting } from "./voting.js"; export const serviceConfigs = { blockscout, + ethGenenisGenerator, lateProverBot, lidoCore, lidoCLI, diff --git a/packages/services/src/embedded/lido-cli.ts b/packages/services/src/embedded/lido-cli.ts index be6eefff..2b8f9001 100644 --- a/packages/services/src/embedded/lido-cli.ts +++ b/packages/services/src/embedded/lido-cli.ts @@ -3,7 +3,7 @@ import { DevnetServiceConfig } from "../devnet-service-config.js"; export const lidoCLI = new DevnetServiceConfig({ repository: { url: "https://github.com/lidofinance/lido-cli.git", - branch: "fix/vroom-306-temp-fix-fusaka-1", + branch: "feature/sr-66-devnet0-1", }, name: "lidoCLI" as const, constants: { diff --git a/packages/services/src/embedded/lido-core.ts b/packages/services/src/embedded/lido-core.ts index 9a0fbce6..8b7a276b 100644 --- a/packages/services/src/embedded/lido-core.ts +++ b/packages/services/src/embedded/lido-core.ts @@ -3,7 +3,7 @@ import { DevnetServiceConfig } from "../devnet-service-config.js"; export const lidoCore = new DevnetServiceConfig({ repository: { url: "git@github.com:lidofinance/core.git", - branch: "develop", + branch: "feat/staking-router-3.0", }, name: "lidoCore" as const, constants: { @@ -13,9 +13,10 @@ export const lidoCore = new DevnetServiceConfig({ GAS_PRIORITY_FEE: "1", NETWORK: "local-devnet", NETWORK_STATE_DEFAULTS_FILE: - "scripts/scratch/deployed-testnet-defaults.json", + "scripts/defaults/local-devnet-defaults.json", NETWORK_STATE_FILE: `deployed-local-devnet.json`, SLOTS_PER_EPOCH: "32", + SCRATCH_DEPLOY_CONFIG: "scripts/scratch/deploy-params-testnet.toml", }, hooks: { install: "lido-core:install", diff --git a/packages/services/src/embedded/oracle.ts b/packages/services/src/embedded/oracle.ts index c6a5f566..0a6bcef8 100644 --- a/packages/services/src/embedded/oracle.ts +++ b/packages/services/src/embedded/oracle.ts @@ -3,7 +3,7 @@ import { DevnetServiceConfig } from "../devnet-service-config.js"; export const oracle = new DevnetServiceConfig({ repository: { url: "https://github.com/lidofinance/lido-oracle.git", - branch: "fix/vroom-306-temp-fix-fusaka-1", + branch: "feat/srv3-accounting", }, workspace: "workspaces/oracle", name: "oracle" as const, diff --git a/src/commands/artifact/dump.ts b/src/commands/artifact/dump.ts new file mode 100644 index 00000000..a17dc949 --- /dev/null +++ b/src/commands/artifact/dump.ts @@ -0,0 +1,54 @@ +import { Params, command } from "@devnet/command"; +import { execa } from "execa"; +import { access } from "node:fs/promises"; +import path from "node:path"; + +export const ArtifactsDump = command.cli({ + description: "Archive network artifacts excluding node_modules", + params: { + output: Params.string({ + description: + "Output path for the archive (default: ./{network-name}.tar.gz)", + required: false, + }), + }, + async handler({ dre, params }) { + const { logger, network } = dre; + const networkName = network.name; + + const artifactsRoot = path.join(process.cwd(), "artifacts"); + const networkArtifactsPath = path.join(artifactsRoot, networkName); + + try { + await access(networkArtifactsPath); + } catch { + logger.error(`Network artifacts not found: ${networkArtifactsPath}`); + throw new Error(`Network "${networkName}" artifacts do not exist`); + } + + const defaultOutput = path.join(process.cwd(), `${networkName}.tar.gz`); + const outputPath = params.output || defaultOutput; + + logger.log(`Archiving artifacts for network: ${networkName}`); + logger.log(`Source: ${networkArtifactsPath}`); + logger.log(`Output: ${outputPath}`); + + try { + const sh = execa({ stdio: "inherit" }); + + logger.log("Creating archive..."); + + // Create tar.gz archive excluding node_modules + await sh`tar -czf ${outputPath} -C ${artifactsRoot} --exclude=node_modules ${networkName}`; + + logger.log(`Archive created successfully: ${outputPath}`); + + const { stdout } = await execa`du -h ${outputPath}`; + const size = stdout.split("\t")[0]; + logger.log(`Archive size: ${size}`); + } catch (error) { + logger.error("Failed to create archive"); + throw error; + } + }, +}); diff --git a/src/commands/artifact/restore.ts b/src/commands/artifact/restore.ts new file mode 100644 index 00000000..ad34fc74 --- /dev/null +++ b/src/commands/artifact/restore.ts @@ -0,0 +1,83 @@ +import { Params, command } from "@devnet/command"; +import { execa } from "execa"; +import { access } from "node:fs/promises"; +import path from "node:path"; + +export const ArtifactsRestore = command.cli({ + description: + "Restore network artifacts from archive and install dependencies", + params: { + archive: Params.string({ + description: + "Path to the archive file (default: ./{network-name}.tar.gz)", + required: false, + }), + skipInstall: Params.boolean({ + description: "Skip installing dependencies", + required: false, + default: false, + }), + }, + async handler({ dre, params }) { + const { logger, network, services } = dre; + const networkName = network.name; + + // Determine archive path + const defaultArchive = path.join(process.cwd(), `${networkName}.tar.gz`); + const archivePath = params.archive || defaultArchive; + + // Check if archive exists + try { + await access(archivePath); + } catch { + logger.error(`Archive not found: ${archivePath}`); + throw new Error(`Archive file does not exist: ${archivePath}`); + } + + const artifactsRoot = path.join(process.cwd(), "artifacts"); + const networkArtifactsPath = path.join(artifactsRoot, networkName); + + logger.log(`Restoring artifacts for network: ${networkName}`); + logger.log(`Archive: ${archivePath}`); + logger.log(`Target: ${networkArtifactsPath}`); + + try { + const sh = execa({ stdio: "inherit" }); + + // Extract archive + logger.log("Extracting archive..."); + await sh`tar -xzf ${archivePath} -C ${artifactsRoot}`; + logger.log("Archive extracted successfully"); + + // Skip dependency installation if requested + if (params.skipInstall) { + logger.log("Skipping dependency installation"); + return; + } + + // Install dependencies for each service + logger.log("Installing dependencies..."); + + for (const [name, service] of Object.entries(services)) { + try { + // Check if package.json exists in the service directory + const packageJsonPath = path.join( + service.artifact.root, + "package.json", + ); + await access(packageJsonPath); + + logger.log(`Installing dependencies for ${name}...`); + await service.sh`yarn install`; + } catch { + logger.log(`Skipped yarn installation for ${name}`); + } + } + + logger.log("Artifacts restored successfully"); + } catch (error) { + logger.error("Failed to restore artifacts"); + throw error; + } + }, +}); diff --git a/src/commands/csm-prover-tool-k8s/up.ts b/src/commands/csm-prover-tool-k8s/up.ts index 54a4cdef..85ab0328 100644 --- a/src/commands/csm-prover-tool-k8s/up.ts +++ b/src/commands/csm-prover-tool-k8s/up.ts @@ -41,6 +41,7 @@ export const CSMProverToolK8sUp = command.cli({ } const { elPrivate, clPrivate } = await state.getChain(); + const { el, cl } = await state.getNodesIngress(); const { verifier: csVerifier, module: csModule } = await state.getCSM(); const { privateUrl: kapiPrivateUrl } = await state.getKapiK8sRunning(); const { deployer } = await state.getNamedWallet(); @@ -49,8 +50,8 @@ export const CSMProverToolK8sUp = command.cli({ ...csmProverTool.config.constants, CHAIN_ID: "32382", - EL_RPC_URLS: elPrivate, - CL_API_URLS: clPrivate, + EL_RPC_URLS: el[1].publicIngressUrl, + CL_API_URLS: cl[1].publicIngressUrl, KEYSAPI_API_URLS: kapiPrivateUrl, CSM_ADDRESS: csModule, VERIFIER_ADDRESS: csVerifier, diff --git a/src/commands/genesis-generator/build.ts b/src/commands/genesis-generator/build.ts new file mode 100644 index 00000000..af9018f5 --- /dev/null +++ b/src/commands/genesis-generator/build.ts @@ -0,0 +1,35 @@ +import { command } from "@devnet/command"; +import { buildAndPushDockerImage } from "@devnet/docker"; + +import { SERVICE_NAME } from "./constants/genesis-generator.constants.js"; +import { genesisGeneratorExtension } from "./extensions/genesis-generator.extension.js"; + +export const GenesisGeneratorK8SBuild = command.isomorphic({ + description: `Build ${SERVICE_NAME} and push to Docker registry`, + params: {}, + extensions: [genesisGeneratorExtension], + async handler({ dre: { state, network, services, logger } }) { + const dockerRegistry = await state.getDockerRegistry(); + + const TAG = `kt-${network.name}`; + const IMAGE = 'lido/lido-genesis-generator'; + + await buildAndPushDockerImage({ + cwd: services.ethGenenisGenerator.artifact.root, + registryHostname: dockerRegistry.registryHostname, + buildContext: '.', + imageName: IMAGE, + tag: TAG, + password: process.env.DOCKER_REGISTRY_PASSWORD ?? 'admin', + username: process.env.DOCKER_REGISTRY_USERNAME ?? 'changeme', + }); + + logger.log(`${SERVICE_NAME} image pushed to ${dockerRegistry.registryUrl}/${IMAGE}:${TAG}`); + + await state.updateGenesisGeneratorImage({ + tag: TAG, + image: IMAGE, + registryHostname: dockerRegistry.registryHostname, + }) + }, +}); diff --git a/src/commands/genesis-generator/constants/genesis-generator.constants.ts b/src/commands/genesis-generator/constants/genesis-generator.constants.ts new file mode 100644 index 00000000..059ec461 --- /dev/null +++ b/src/commands/genesis-generator/constants/genesis-generator.constants.ts @@ -0,0 +1,6 @@ +import { DevNetRuntimeEnvironmentInterface } from "@devnet/command"; + +export const NAMESPACE = (dre: DevNetRuntimeEnvironmentInterface) => + `kt-${dre.network.name}-genesis-generator`; + +export const SERVICE_NAME = "Ethereum Genesis Generator"; diff --git a/src/commands/genesis-generator/extensions/genesis-generator.extension.ts b/src/commands/genesis-generator/extensions/genesis-generator.extension.ts new file mode 100644 index 00000000..da75c0c9 --- /dev/null +++ b/src/commands/genesis-generator/extensions/genesis-generator.extension.ts @@ -0,0 +1,86 @@ +import { DevNetRuntimeEnvironmentInterface } from "@devnet/command"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { Config, StateInterface } from "@devnet/state"; +import { isEmptyObject } from "@devnet/utils"; +import { z } from "zod"; + + +// augmenting the StateInterface +declare module "@devnet/state" { + export interface StateInterface { + getGenesisGeneratorImage(must?: M,): Promise>; + getGenesisGeneratorState(must?: M,): Promise>; + + isGenesisGeneratorImageReady(): Promise; + + removeGenesisGeneratorState(): Promise; + + updateGenesisGeneratorImage(state: GenesisGeneratorStateImage): Promise; + } + + export interface Config { + genesisGeneratorK8s: GenesisGeneratorState; + } +} + +export const GenesisGeneratorStateImage = z.object({ + image: z.string(), + tag: z.string(), + registryHostname: z.string() +}); + +export type GenesisGeneratorStateImage = z.infer; + +export const GenesisGeneratorStateRunning = z.object({ + helmRelease: z.string(), +}); + +export type GenesisGeneratorStateRunning = z.infer; + +export const GenesisGeneratorState = z.object({ + image: GenesisGeneratorStateImage.optional(), +}); + +export type GenesisGeneratorState = z.infer; + +export const genesisGeneratorExtension = (dre: DevNetRuntimeEnvironmentInterface) => { + dre.state.updateGenesisGeneratorImage = (async function (stateImage: GenesisGeneratorStateImage) { + const state = await dre.state.getGenesisGeneratorState(false); + await dre.state.updateProperties("genesisGenerator", { ...state, image: stateImage }); + }); + + dre.state.removeGenesisGeneratorState = (async function () { + await dre.state.updateProperties("genesisGenerator", {}); + }); + + dre.state.isGenesisGeneratorImageReady = (async function () { + const state = await dre.state.getGenesisGeneratorImage(false); + return state && !isEmptyObject(state) && (state.image !== undefined); + }); + + dre.state.getGenesisGeneratorImage = (async function (must: M = true as M) { + return dre.state.getProperties( + { + image: "genesisGenerator.image.image", + tag: "genesisGenerator.image.tag", + registryHostname: "genesisGenerator.image.registryHostname", + }, + "genesisGeneratorK8s", + GenesisGeneratorStateImage, + must, + ); + }); + + dre.state.getGenesisGeneratorState = (async function (must: M = true as M) { + return dre.state.getProperties( + 'genesisGenerator', + "genesisGeneratorK8s", + GenesisGeneratorState, + must, + ); + }); +}; diff --git a/src/commands/kurtosis/run-package.ts b/src/commands/kurtosis/run-package.ts index 0fc628bc..10b630f3 100644 --- a/src/commands/kurtosis/run-package.ts +++ b/src/commands/kurtosis/run-package.ts @@ -49,7 +49,7 @@ export const KurtosisRunPackage = command.isomorphic({ await kurtosis.sh`kurtosis run --enclave ${dre.network.name} - github.com/ethpandaops/ethereum-package + github.com/lidofinance/ethereum-package --production --args-file ${configFileName}`; diff --git a/src/commands/lido-core/add-new-operator.ts b/src/commands/lido-core/add-new-operator.ts index c0a81e91..1dca52cc 100644 --- a/src/commands/lido-core/add-new-operator.ts +++ b/src/commands/lido-core/add-new-operator.ts @@ -17,24 +17,41 @@ export const AddNewOperator = command.cli({ description: "Operator ID to be used for the new operator.", default: 1, }), + depositCount: Params.integer({ + description: "Number of deposits to be made for the new operator.", + default: 30, + }), + stakingModuleId: Params.integer({ + description: "Staking module ID to be used for the new operator.", + default: 1, + }), + dsm: Params.boolean({ + description: "Use full DSM setup.", + default: false, + }), }, async handler({ params, dre, dre: { logger, services } }) { - const depositArgs = { dsm: false }; + const depositArgs = { dsm: params.dsm }; const OPERATOR_ID = params.operatorId; + const STAKING_MODULE_ID = params.stakingModuleId ?? 1; + const NOR_DEVNET_OPERATOR = `devnet_nor_${OPERATOR_ID}`; + const DEPOSIT_COUNT = params.depositCount ?? 30; assert( OPERATOR_ID > 0, `Operator ID must be greater than 0, got ${OPERATOR_ID}`, ); - - const NOR_DEVNET_OPERATOR = `devnet_nor_${OPERATOR_ID}`; - - const DEPOSIT_COUNT = 100; + assert( + STAKING_MODULE_ID > 0, + `Staking Module ID must be greater than 0, got ${STAKING_MODULE_ID}`, + ); const operatorExists = await services.lidoCLI.fileExists( `generated-keys/${NOR_DEVNET_OPERATOR}.json`, ); + const operatorId = OPERATOR_ID - 1; + assert(!operatorExists, `Operator ${NOR_DEVNET_OPERATOR} already exists.`); logger.log("🚀 Generating and allocating keys for NOR Module..."); @@ -49,20 +66,20 @@ export const AddNewOperator = command.cli({ logger.log("🚀 Adding NOR keys..."); await dre.runCommand(LidoAddKeys, { name: NOR_DEVNET_OPERATOR, - id: OPERATOR_ID, + id: operatorId, }); logger.log("✅ NOR keys added."); logger.log("🚀 Increasing staking limit for NOR..."); await dre.runCommand(LidoSetStakingLimit, { - operatorId: OPERATOR_ID, + operatorId, limit: DEPOSIT_COUNT, }); logger.log("✅ Staking limit for NOR increased."); logger.log("🚀 Making deposit to NOR..."); await dre.runCommand(LidoDeposit, { - id: 1, + id: STAKING_MODULE_ID, deposits: DEPOSIT_COUNT, ...depositArgs, }); diff --git a/src/commands/lido-core/deploy-tw.ts b/src/commands/lido-core/deploy-tw.ts index 42e161b1..210f0155 100644 --- a/src/commands/lido-core/deploy-tw.ts +++ b/src/commands/lido-core/deploy-tw.ts @@ -1,4 +1,4 @@ -import { command } from "@devnet/command"; +import { Params, command } from "@devnet/command"; import { PrepareLidoCore } from "./prepare-repository.js"; import { LidoCoreUpdateState } from "./update-state.js"; @@ -22,7 +22,12 @@ type DeployEnvRequired = { export const DeployTWContracts = command.cli({ description: "Deploys lido-core smart contracts using configured deployment scripts.", - params: {}, + params: { + configFile: Params.string({ + description: "Path to configuration file (supports .toml and .json)", + required: true, + }), + }, async handler({ dre, dre: { logger } }) { const { state, services, network } = dre; const { lidoCore } = services; @@ -59,9 +64,20 @@ export const DeployTWContracts = command.cli({ }; await dre.runCommand(PrepareLidoCore, { + configFile: undefined, objectionPhaseDuration: 5, voteDuration: 60, vesting: "820000000000000000000000", + normalizedClRewardPerEpoch: 64, + normalizedClRewardMistakeRateBp: 1000, + rebaseCheckNearestEpochDistance: 1, + rebaseCheckDistantEpochDistance: 2, + validatorDelayedTimeoutInSlots: 7200, + validatorDelinquentTimeoutInSlots: 28_800, + nodeOperatorNetworkPenetrationThresholdBp: 100, + predictionDurationInSlots: 50_400, + finalizationMaxNegativeRebaseEpochShift: 1350, + exitEventsLookbackWindowInSlots: 7200, }); await lidoCore.sh({ diff --git a/src/commands/lido-core/deploy.ts b/src/commands/lido-core/deploy.ts index 3c559d84..441424b8 100644 --- a/src/commands/lido-core/deploy.ts +++ b/src/commands/lido-core/deploy.ts @@ -8,6 +8,7 @@ import { LidoCoreVerify } from "./verify.js"; type DeployEnvRequired = { DEPLOYER: string; DEPOSIT_CONTRACT: string; + GAS_LIMIT?: string; GAS_MAX_FEE: string; GAS_PRIORITY_FEE: string; GENESIS_TIME: string; @@ -16,19 +17,73 @@ type DeployEnvRequired = { NETWORK_STATE_DEFAULTS_FILE: string; NETWORK_STATE_FILE: string; RPC_URL: string; + SCRATCH_DEPLOY_CONFIG?: string; SLOTS_PER_EPOCH: string; - GAS_LIMIT?: string; }; export const DeployLidoContracts = command.cli({ description: "Deploys lido-core smart contracts using configured deployment scripts.", params: { + configFile: Params.string({ + description: "Path to configuration file (supports .toml and .json)", + required: true, + }), verify: Params.boolean({ description: "Verify smart contracts", default: false, required: true, }), + normalizedClRewardPerEpoch: Params.integer({ + description: "Normalized CL reward per epoch", + default: 64, + required: false, + }), + normalizedClRewardMistakeRateBp: Params.integer({ + description: "Normalized CL reward mistake rate in basis points", + default: 1000, + required: false, + }), + rebaseCheckNearestEpochDistance: Params.integer({ + description: "Rebase check nearest epoch distance", + default: 1, + required: false, + }), + rebaseCheckDistantEpochDistance: Params.integer({ + description: "Rebase check distant epoch distance", + default: 2, + required: false, + }), + validatorDelayedTimeoutInSlots: Params.integer({ + description: "Validator delayed timeout in slots", + default: 7200, + required: false, + }), + validatorDelinquentTimeoutInSlots: Params.integer({ + description: "Validator delinquent timeout in slots", + default: 28_800, + required: false, + }), + nodeOperatorNetworkPenetrationThresholdBp: Params.integer({ + description: "Node operator network penetration threshold in basis points", + default: 100, + required: false, + }), + predictionDurationInSlots: Params.integer({ + description: "Prediction duration in slots", + default: 50_400, + required: false, + }), + finalizationMaxNegativeRebaseEpochShift: Params.integer({ + description: "Finalization max negative rebase epoch shift", + default: 1350, + required: false, + }), + exitEventsLookbackWindowInSlots: Params.integer({ + description: "Exit events lookback window in slots", + default: 7200, + required: false, + }), }, extensions:[lidoCoreExtension], async handler({ dre, dre: { logger }, params }) { @@ -54,9 +109,20 @@ export const DeployLidoContracts = command.cli({ await dre.network.waitEL(); await dre.runCommand(PrepareLidoCore, { + configFile: params.configFile, objectionPhaseDuration: 5, voteDuration: 60, vesting: "820000000000000000000000", + normalizedClRewardPerEpoch: params.normalizedClRewardPerEpoch, + normalizedClRewardMistakeRateBp: params.normalizedClRewardMistakeRateBp, + rebaseCheckNearestEpochDistance: params.rebaseCheckNearestEpochDistance, + rebaseCheckDistantEpochDistance: params.rebaseCheckDistantEpochDistance, + validatorDelayedTimeoutInSlots: params.validatorDelayedTimeoutInSlots, + validatorDelinquentTimeoutInSlots: params.validatorDelinquentTimeoutInSlots, + nodeOperatorNetworkPenetrationThresholdBp: params.nodeOperatorNetworkPenetrationThresholdBp, + predictionDurationInSlots: params.predictionDurationInSlots, + finalizationMaxNegativeRebaseEpochShift: params.finalizationMaxNegativeRebaseEpochShift, + exitEventsLookbackWindowInSlots: params.exitEventsLookbackWindowInSlots, }); const DEPOSIT_CONTRACT_ADDRESS = await dre.services.kurtosis.config.getters.DEPOSIT_CONTRACT_ADDRESS(dre.services.kurtosis); @@ -72,6 +138,7 @@ export const DeployLidoContracts = command.cli({ NETWORK: constants.NETWORK, NETWORK_STATE_DEFAULTS_FILE: constants.NETWORK_STATE_DEFAULTS_FILE, NETWORK_STATE_FILE: constants.NETWORK_STATE_FILE, + SCRATCH_DEPLOY_CONFIG: constants.SCRATCH_DEPLOY_CONFIG, GENESIS_TIME: genesis_time, RPC_URL: elPublic, SLOTS_PER_EPOCH: constants.SLOTS_PER_EPOCH, diff --git a/src/commands/lido-core/prepare-repository.ts b/src/commands/lido-core/prepare-repository.ts index 6e126840..1ae5a18a 100644 --- a/src/commands/lido-core/prepare-repository.ts +++ b/src/commands/lido-core/prepare-repository.ts @@ -4,6 +4,10 @@ import { assert } from "@devnet/utils"; export const PrepareLidoCore = command.cli({ description: "Prepare lido core repository.", params: { + configFile: Params.string({ + description: "Path to configuration file (supports .toml and .json)", + required: false, + }), vesting: Params.string({ description: "Vesting LDO amount", default: "820000000000000000000000", @@ -19,82 +23,190 @@ export const PrepareLidoCore = command.cli({ default: 5, required: false, }), + normalizedClRewardPerEpoch: Params.integer({ + description: "Normalized CL reward per epoch", + default: 64, + required: false, + }), + normalizedClRewardMistakeRateBp: Params.integer({ + description: "Normalized CL reward mistake rate in basis points", + default: 1000, + required: false, + }), + rebaseCheckNearestEpochDistance: Params.integer({ + description: "Rebase check nearest epoch distance", + default: 1, + required: false, + }), + rebaseCheckDistantEpochDistance: Params.integer({ + description: "Rebase check distant epoch distance", + default: 2, + required: false, + }), + validatorDelayedTimeoutInSlots: Params.integer({ + description: "Validator delayed timeout in slots", + default: 7200, + required: false, + }), + validatorDelinquentTimeoutInSlots: Params.integer({ + description: "Validator delinquent timeout in slots", + default: 28_800, + required: false, + }), + nodeOperatorNetworkPenetrationThresholdBp: Params.integer({ + description: + "Node operator network penetration threshold in basis points", + default: 100, + required: false, + }), + predictionDurationInSlots: Params.integer({ + description: "Prediction duration in slots", + default: 50_400, + required: false, + }), + finalizationMaxNegativeRebaseEpochShift: Params.integer({ + description: "Finalization max negative rebase epoch shift", + default: 1350, + required: false, + }), + exitEventsLookbackWindowInSlots: Params.integer({ + description: "Exit events lookback window in slots", + default: 7200, + required: false, + }), }, async handler({ dre, - params: { voteDuration, objectionPhaseDuration, vesting }, + params: { + configFile, + voteDuration, + objectionPhaseDuration, + vesting, + normalizedClRewardPerEpoch, + normalizedClRewardMistakeRateBp, + rebaseCheckNearestEpochDistance, + rebaseCheckDistantEpochDistance, + validatorDelayedTimeoutInSlots, + validatorDelinquentTimeoutInSlots, + nodeOperatorNetworkPenetrationThresholdBp, + predictionDurationInSlots, + finalizationMaxNegativeRebaseEpochShift, + exitEventsLookbackWindowInSlots, + }, }) { const { state, services } = dre; const { lidoCore, oracle } = services; const { constants } = lidoCore.config; const { deployer, secondDeployer } = await state.getNamedWallet(); - const filePath = constants.NETWORK_STATE_DEFAULTS_FILE; - const networkStateDefaults = await lidoCore.readJson(filePath); + const filePath = configFile || constants.NETWORK_STATE_DEFAULTS_FILE; + const fileExtension = filePath.split(".").pop()?.toLowerCase(); - const { - vestingParams, - daoInitialSettings, - oracleDaemonConfig, - hashConsensusForAccountingOracle, - hashConsensusForValidatorsExitBusOracle, - } = networkStateDefaults; - assert(vestingParams?.holders, "Missing vestingParams.holders"); - assert(daoInitialSettings?.voting, "Missing daoInitialSettings.voting"); - assert(oracleDaemonConfig, "Missing oracleDaemonConfig"); + let configObj: any; + if (fileExtension === "json") { + configObj = await lidoCore.readJson(filePath); + } else if (fileExtension === "toml") { + configObj = await lidoCore.readToml(filePath); + } else { + throw new Error(`Unsupported file extension: ${fileExtension}. Supported formats: .json, .toml`); + } + + console.log(`📄 Config file parsed (${filePath}):`, JSON.stringify(configObj, null, 2)); + + const vestingParams = configObj.vesting || {}; + const daoObj = configObj.dao || {}; + const initialSettings = daoObj.initialSettings || {}; + const daoVoting = initialSettings.voting || {}; + const oracleDaemonConfig = configObj.oracleDaemonConfig || {}; + const hashConsensusAO = configObj.hashConsensusForAccountingOracle || {}; + const hashConsensusVEBO = + configObj.hashConsensusForValidatorsExitBusOracle || {}; + + assert( + vestingParams.holders !== undefined, + "Missing vestingParams.holders", + ); assert( - hashConsensusForAccountingOracle, + initialSettings.voting !== undefined, + "Missing initialSettings.voting", + ); + assert(oracleDaemonConfig !== undefined, "Missing oracleDaemonConfig"); + assert( + configObj.hashConsensusForAccountingOracle !== undefined, "Missing hashConsensusForAccountingOracle", ); assert( - hashConsensusForValidatorsExitBusOracle, + configObj.hashConsensusForValidatorsExitBusOracle !== undefined, "Missing hashConsensusForValidatorsExitBusOracle", ); - Object.assign(vestingParams.holders, { + vestingParams.holders = { + ...vestingParams.holders, [deployer.publicKey]: vesting, [secondDeployer.publicKey]: vesting, - }); + }; - Object.assign(daoInitialSettings.voting, { - voteDuration, - objectionPhaseDuration, - }); - - Object.assign(oracleDaemonConfig, { - deployParameters: { - NORMALIZED_CL_REWARD_PER_EPOCH: 64, - NORMALIZED_CL_REWARD_MISTAKE_RATE_BP: 1000, - REBASE_CHECK_NEAREST_EPOCH_DISTANCE: 1, - REBASE_CHECK_DISTANT_EPOCH_DISTANCE: 2, - VALIDATOR_DELAYED_TIMEOUT_IN_SLOTS: 7200, - VALIDATOR_DELINQUENT_TIMEOUT_IN_SLOTS: 28_800, - NODE_OPERATOR_NETWORK_PENETRATION_THRESHOLD_BP: 100, - PREDICTION_DURATION_IN_SLOTS: 50_400, - FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT: 1350, - EXIT_EVENTS_LOOKBACK_WINDOW_IN_SLOTS: 100_800 - }, - }); + daoVoting.voteDuration = voteDuration; + daoVoting.objectionPhaseDuration = objectionPhaseDuration; + + const deployParameters = { + NORMALIZED_CL_REWARD_PER_EPOCH: normalizedClRewardPerEpoch, + NORMALIZED_CL_REWARD_MISTAKE_RATE_BP: normalizedClRewardMistakeRateBp, + REBASE_CHECK_NEAREST_EPOCH_DISTANCE: rebaseCheckNearestEpochDistance, + REBASE_CHECK_DISTANT_EPOCH_DISTANCE: rebaseCheckDistantEpochDistance, + VALIDATOR_DELAYED_TIMEOUT_IN_SLOTS: validatorDelayedTimeoutInSlots, + VALIDATOR_DELINQUENT_TIMEOUT_IN_SLOTS: validatorDelinquentTimeoutInSlots, + NODE_OPERATOR_NETWORK_PENETRATION_THRESHOLD_BP: + nodeOperatorNetworkPenetrationThresholdBp, + PREDICTION_DURATION_IN_SLOTS: predictionDurationInSlots, + FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT: + finalizationMaxNegativeRebaseEpochShift, + EXIT_EVENTS_LOOKBACK_WINDOW_IN_SLOTS: exitEventsLookbackWindowInSlots, + }; + + if (fileExtension === "toml") { + // For TOML files, write parameters directly to oracleDaemonConfig + Object.assign(oracleDaemonConfig, deployParameters); + } else { + // For JSON files, write parameters to deployParameters object + oracleDaemonConfig.deployParameters = deployParameters; + } const { HASH_CONSENSUS_AO_EPOCHS_PER_FRAME, HASH_CONSENSUS_VEBO_EPOCHS_PER_FRAME, } = oracle.config.constants; - Object.assign(hashConsensusForAccountingOracle, { - deployParameters: { - fastLaneLengthSlots: 10, - epochsPerFrame: HASH_CONSENSUS_AO_EPOCHS_PER_FRAME, - }, - }); - - Object.assign(hashConsensusForValidatorsExitBusOracle, { - deployParameters: { - fastLaneLengthSlots: 10, - epochsPerFrame: HASH_CONSENSUS_VEBO_EPOCHS_PER_FRAME, - }, - }); - - await lidoCore.writeJson(filePath, networkStateDefaults, true); + const hashConsensusAOParams = { + fastLaneLengthSlots: 10, + epochsPerFrame: HASH_CONSENSUS_AO_EPOCHS_PER_FRAME, + }; + + const hashConsensusVEBOParams = { + fastLaneLengthSlots: 10, + epochsPerFrame: HASH_CONSENSUS_VEBO_EPOCHS_PER_FRAME, + }; + + if (fileExtension === "toml") { + // For TOML files, write parameters directly to objects + Object.assign(hashConsensusAO, hashConsensusAOParams); + Object.assign(hashConsensusVEBO, hashConsensusVEBOParams); + } else { + // For JSON files, write parameters to deployParameters objects + hashConsensusAO.deployParameters = hashConsensusAOParams; + hashConsensusVEBO.deployParameters = hashConsensusVEBOParams; + } + + configObj.vesting = vestingParams; + configObj.dao = daoObj; + configObj.dao.initialSettings = initialSettings; + configObj.dao.initialSettings.voting = daoVoting; + configObj.oracleDaemonConfig = oracleDaemonConfig; + configObj.hashConsensusForAccountingOracle = hashConsensusAO; + configObj.hashConsensusForValidatorsExitBusOracle = hashConsensusVEBO; + + await (fileExtension === "json" + ? lidoCore.writeJson(filePath, configObj) + : lidoCore.writeToml(filePath, configObj)); }, }); diff --git a/src/commands/ssh/tunnel.ts b/src/commands/ssh/tunnel.ts index 9961222d..c54e0b4c 100644 --- a/src/commands/ssh/tunnel.ts +++ b/src/commands/ssh/tunnel.ts @@ -10,10 +10,15 @@ export const SSHTunnel = command.cli({ async handler({ dre: { logger } }) { const sshHost = process.env.SSH_HOST; const sshUser = process.env.SSH_USER ?? process.env.USER; - const sshPrivateKey = process.env.SSH_PRIVATE_KEY ?? '~/.ssh/id_rsa'; + const sshPrivateKey = process.env.SSH_PRIVATE_KEY; const sshTunnelRemoteAddress = process.env.SSH_TUNNEL_REMOTE_ADDRESS; const sshTunnelLocalPort = process.env.SSH_TUNNEL_LOCAL_PORT; + const sshPrivateKeyCmdParams: string[] = []; + if (sshPrivateKey) { + sshPrivateKeyCmdParams.push('-i', sshPrivateKey); + } + // Validate required environment variables if (!sshHost) { throw new DevNetError("SSH_HOST environment variable is required"); @@ -23,10 +28,6 @@ export const SSHTunnel = command.cli({ throw new DevNetError("SSH_USER environment variable is required"); } - if (!sshPrivateKey) { - throw new DevNetError("SSH_PRIVATE_KEY environment variable is required"); - } - if (!sshTunnelRemoteAddress) { throw new DevNetError("SSH_TUNNEL_REMOTE_ADDRESS environment variable is required"); } @@ -39,10 +40,12 @@ export const SSHTunnel = command.cli({ logger.log(`Tunnel configuration: ${sshTunnelLocalPort} -> ${sshTunnelRemoteAddress}`); const sshArgs = [ - '-i', sshPrivateKey, + ...sshPrivateKeyCmdParams, '-L', `${sshTunnelLocalPort}:${sshTunnelRemoteAddress}`, '-N', // Don't execute a remote command '-T', // Disable pseudo-terminal allocation + '-o', 'ServerAliveInterval=30', + '-o', 'ServerAliveCountMax=3', `${sshUser}@${sshHost}` ]; diff --git a/src/commands/stands/csm-v2.ts b/src/commands/stands/csm-v2.ts index 7bf2286f..b432bc0e 100644 --- a/src/commands/stands/csm-v2.ts +++ b/src/commands/stands/csm-v2.ts @@ -69,7 +69,20 @@ export const PectraDevNetUp = command.cli({ const depositArgs = { dsm: params.dsm }; logger.log("🚀 Deploying Lido Core contracts..."); - await dre.runCommand(DeployLidoContracts, deployArgs); + await dre.runCommand(DeployLidoContracts, { + ...deployArgs, + configFile: dre.services.lidoCore.config.constants.NETWORK_STATE_DEFAULTS_FILE, + normalizedClRewardPerEpoch: 64, + normalizedClRewardMistakeRateBp: 1000, + rebaseCheckNearestEpochDistance: 1, + rebaseCheckDistantEpochDistance: 2, + validatorDelayedTimeoutInSlots: 7200, + validatorDelinquentTimeoutInSlots: 28_800, + nodeOperatorNetworkPenetrationThresholdBp: 100, + predictionDurationInSlots: 50_400, + finalizationMaxNegativeRebaseEpochShift: 1350, + exitEventsLookbackWindowInSlots: 7200, + }); logger.log("✅ Lido contracts deployed."); logger.log("🚀 Deploying CSM contracts..."); @@ -84,8 +97,8 @@ export const PectraDevNetUp = command.cli({ logger.log("🚀 Activating CSM module..."); await dre.runCommand(ActivateCSM, { - stakeShareLimitBP: 10000, - priorityExitShareThresholdBP: 10000, + stakeShareLimitBP: 10_000, + priorityExitShareThresholdBP: 10_000, maxDepositsPerBlock: 100, }); logger.log("✅ CSM module activated."); @@ -120,7 +133,7 @@ export const PectraDevNetUp = command.cli({ await dre.runCommand(KapiK8sUp, {}); logger.log("🚀 Run Oracle service."); - await dre.runCommand(OracleK8sUp, { tag: '6.0.1', build: false }); + await dre.runCommand(OracleK8sUp, { tag: "6.0.1", build: false }); if (params.dsm) { logger.log("🚀 Deploying Data-bus..."); diff --git a/src/commands/stands/fusaka-srv3-devnet0-consolidation.ts b/src/commands/stands/fusaka-srv3-devnet0-consolidation.ts new file mode 100644 index 00000000..85a35797 --- /dev/null +++ b/src/commands/stands/fusaka-srv3-devnet0-consolidation.ts @@ -0,0 +1,114 @@ +import { Params, command } from "@devnet/command"; + +import { ChainGetInfo } from "../chain/info.js"; +import { ChainUp } from "../chain/up.js"; +import { CouncilK8sUp } from "../council-k8s/up.js"; +import { DeployCSMContracts } from "../csm/deploy.js"; +import { DataBusDeploy } from "../data-bus/deploy.js"; +import { DSMBotsK8sUp } from "../dsm-bots-k8s/up.js"; +import { GitCheckout } from "../git/checkout.js"; +import { KapiK8sUp } from "../kapi-k8s/up.js"; +import { ActivateLidoProtocol } from "../lido-core/activate.js"; +import { AddNewOperator } from "../lido-core/add-new-operator.js"; +import { DeployLidoContracts } from "../lido-core/deploy.js"; +import { ReplaceDSM } from "../lido-core/replace-dsm.js"; +import { OracleK8sUp } from "../oracles-k8s/up.js"; + +export const FusakaSRV3DevNetConsolidationUp = command.cli({ + description: "Staking Router V3 Devnet0 on Fusaka test stand.", + params: { + verify: Params.boolean({ + description: "Enables verification of smart contracts during deployment.", + }), + dsm: Params.boolean({ + description: "Use full DSM setup.", + default: false, + }), + preset: Params.string({ + description: "Kurtosis preset name", + default: "fusaka-devnet2", + }), + }, + async handler({ params, dre, dre: { logger } }) { + await dre.runCommand(GitCheckout, { + service: "lidoCore", + ref: "feat/staking-router-3.0", + }); + + await dre.runCommand(GitCheckout, { + service: "csm", + ref: "main", + }); + + await dre.runCommand(ChainUp, { preset: params.preset }); + logger.log("✅ Network initialized."); + + const deployArgs = { verify: false }; + const depositArgs = { dsm: params.dsm }; + + logger.log("🚀 Deploying Lido Core contracts..."); + await dre.runCommand(DeployLidoContracts, { + ...deployArgs, + configFile: dre.services.lidoCore.config.constants.SCRATCH_DEPLOY_CONFIG, + normalizedClRewardPerEpoch: 64, + normalizedClRewardMistakeRateBp: 1000, + rebaseCheckNearestEpochDistance: 1, + rebaseCheckDistantEpochDistance: 2, + validatorDelayedTimeoutInSlots: 7200, + validatorDelinquentTimeoutInSlots: 28_800, + nodeOperatorNetworkPenetrationThresholdBp: 100, + predictionDurationInSlots: 50_400, + finalizationMaxNegativeRebaseEpochShift: 1350, + exitEventsLookbackWindowInSlots: 7200, + }); + logger.log("✅ Lido contracts deployed."); + + logger.log("🚀 Deploying CSM contracts..."); + await dre.runCommand(DeployCSMContracts, deployArgs); + logger.log("✅ CSM contracts deployed."); + + await dre.runCommand(GitCheckout, { + service: "lidoCLI", + ref: "feature/sr-66-devnet0-1", + }); + + logger.log("🚀 Activating Lido Core protocol..."); + await dre.runCommand(ActivateLidoProtocol, {}); + logger.log("✅ Lido Core protocol activated."); + + if (!params.dsm) { + logger.log("🚀 Replacing DSM with an EOA..."); + await dre.runCommand(ReplaceDSM, {}); + logger.log("✅ DSM replaced with an EOA."); + } + + const validators = 30; + logger.log("🚀 Adding 3 new operators with validators..."); + await dre.runCommand(AddNewOperator, { ...depositArgs, operatorId: 2, stakingModuleId: 1, depositCount: validators}); + await dre.runCommand(AddNewOperator, { ...depositArgs, operatorId: 1, stakingModuleId: 1, depositCount: validators}); + await dre.runCommand(AddNewOperator, { ...depositArgs, operatorId: 3, stakingModuleId: 1, depositCount: validators}); + logger.log("✅ 3 new operators with validators added."); + + logger.log("🚀 Run KAPI service in K8s."); + await dre.runCommand(KapiK8sUp, {}); + + logger.log("🚀 Run Oracle service in K8s."); + await dre.runCommand(OracleK8sUp, { tag: "6.0.1", build: false }); + + if (params.dsm) { + logger.log("🚀 Deploying Data-bus..."); + await dre.runCommand(DataBusDeploy, {}); + logger.log("✅ Data-bus deployed."); + + logger.log("🚀 Running Council service..."); + await dre.runCommand(CouncilK8sUp, {}); + logger.log("✅ Council service started."); + + logger.log("🚀 Running DSM-bots service..."); + await dre.runCommand(DSMBotsK8sUp, {}); + logger.log("✅ DSM-bots service started."); + } + + await dre.runCommand(ChainGetInfo, {}); + }, +}); diff --git a/src/commands/stands/fusaka-srv3-devnet0.ts b/src/commands/stands/fusaka-srv3-devnet0.ts new file mode 100644 index 00000000..50960c99 --- /dev/null +++ b/src/commands/stands/fusaka-srv3-devnet0.ts @@ -0,0 +1,114 @@ +import { Params, command } from "@devnet/command"; + +import { ChainGetInfo } from "../chain/info.js"; +import { ChainUp } from "../chain/up.js"; +import { CouncilK8sUp } from "../council-k8s/up.js"; +import { DeployCSMContracts } from "../csm/deploy.js"; +import { DataBusDeploy } from "../data-bus/deploy.js"; +import { DSMBotsK8sUp } from "../dsm-bots-k8s/up.js"; +import { GitCheckout } from "../git/checkout.js"; +import { KapiK8sUp } from "../kapi-k8s/up.js"; +import { ActivateLidoProtocol } from "../lido-core/activate.js"; +import { AddNewOperator } from "../lido-core/add-new-operator.js"; +import { DeployLidoContracts } from "../lido-core/deploy.js"; +import { ReplaceDSM } from "../lido-core/replace-dsm.js"; +import { OracleK8sUp } from "../oracles-k8s/up.js"; + +export const FusakaSRV3DevNetUp = command.cli({ + description: "Staking Router V3 Devnet0 on Fusaka test stand.", + params: { + verify: Params.boolean({ + description: "Enables verification of smart contracts during deployment.", + }), + dsm: Params.boolean({ + description: "Use full DSM setup.", + default: false, + }), + preset: Params.string({ + description: "Kurtosis preset name", + default: "fusaka-devnet2", + }), + }, + async handler({ params, dre, dre: { logger } }) { + await dre.runCommand(GitCheckout, { + service: "lidoCore", + ref: "feat/staking-router-3.0", + }); + + await dre.runCommand(GitCheckout, { + service: "csm", + ref: "main", + }); + + await dre.runCommand(ChainUp, { preset: params.preset }); + logger.log("✅ Network initialized."); + + const deployArgs = { verify: false }; + const depositArgs = { dsm: params.dsm }; + + logger.log("🚀 Deploying Lido Core contracts..."); + await dre.runCommand(DeployLidoContracts, { + ...deployArgs, + configFile: dre.services.lidoCore.config.constants.SCRATCH_DEPLOY_CONFIG, + normalizedClRewardPerEpoch: 64, + normalizedClRewardMistakeRateBp: 1000, + rebaseCheckNearestEpochDistance: 1, + rebaseCheckDistantEpochDistance: 2, + validatorDelayedTimeoutInSlots: 7200, + validatorDelinquentTimeoutInSlots: 28_800, + nodeOperatorNetworkPenetrationThresholdBp: 100, + predictionDurationInSlots: 50_400, + finalizationMaxNegativeRebaseEpochShift: 1350, + exitEventsLookbackWindowInSlots: 7200, + }); + logger.log("✅ Lido contracts deployed."); + + logger.log("🚀 Deploying CSM contracts..."); + await dre.runCommand(DeployCSMContracts, deployArgs); + logger.log("✅ CSM contracts deployed."); + + await dre.runCommand(GitCheckout, { + service: "lidoCLI", + ref: "feature/sr-66-devnet0-1", + }); + + logger.log("🚀 Activating Lido Core protocol..."); + await dre.runCommand(ActivateLidoProtocol, {}); + logger.log("✅ Lido Core protocol activated."); + + if (!params.dsm) { + logger.log("🚀 Replacing DSM with an EOA..."); + await dre.runCommand(ReplaceDSM, {}); + logger.log("✅ DSM replaced with an EOA."); + } + + const validators = 30; + logger.log("🚀 Adding 3 new operators with validators..."); + await dre.runCommand(AddNewOperator, { ...depositArgs, operatorId: 2, stakingModuleId: 1, depositCount: validators}); + await dre.runCommand(AddNewOperator, { ...depositArgs, operatorId: 1, stakingModuleId: 1, depositCount: validators}); + await dre.runCommand(AddNewOperator, { ...depositArgs, operatorId: 3, stakingModuleId: 1, depositCount: validators}); + logger.log("✅ 3 new operators with validators added."); + + logger.log("🚀 Run KAPI service in K8s."); + await dre.runCommand(KapiK8sUp, {}); + + logger.log("🚀 Run Oracle service in K8s."); + await dre.runCommand(OracleK8sUp, { tag: "6.0.1", build: false }); + + if (params.dsm) { + logger.log("🚀 Deploying Data-bus..."); + await dre.runCommand(DataBusDeploy, {}); + logger.log("✅ Data-bus deployed."); + + logger.log("🚀 Running Council service..."); + await dre.runCommand(CouncilK8sUp, {}); + logger.log("✅ Council service started."); + + logger.log("🚀 Running DSM-bots service..."); + await dre.runCommand(DSMBotsK8sUp, {}); + logger.log("✅ DSM-bots service started."); + } + + await dre.runCommand(ChainGetInfo, {}); + }, +}); diff --git a/src/commands/stands/fusaka.ts b/src/commands/stands/fusaka.ts index cd9e4b97..eb1258e7 100644 --- a/src/commands/stands/fusaka.ts +++ b/src/commands/stands/fusaka.ts @@ -48,7 +48,7 @@ export const FusakaDevNetUp = command.cli({ await dre.runCommand(GitCheckout, { service: "csm", - ref: "main", + ref: "develop", }); await dre.runCommand(GitCheckout, { @@ -63,7 +63,20 @@ export const FusakaDevNetUp = command.cli({ const depositArgs = { dsm: params.dsm }; logger.log("🚀 Deploying Lido Core contracts..."); - await dre.runCommand(DeployLidoContracts, deployArgs); + await dre.runCommand(DeployLidoContracts, { + ...deployArgs, + configFile: dre.services.lidoCore.config.constants.NETWORK_STATE_DEFAULTS_FILE, + normalizedClRewardPerEpoch: 64, + normalizedClRewardMistakeRateBp: 1000, + rebaseCheckNearestEpochDistance: 1, + rebaseCheckDistantEpochDistance: 2, + validatorDelayedTimeoutInSlots: 7200, + validatorDelinquentTimeoutInSlots: 28_800, + nodeOperatorNetworkPenetrationThresholdBp: 100, + predictionDurationInSlots: 50_400, + finalizationMaxNegativeRebaseEpochShift: 1350, + exitEventsLookbackWindowInSlots: 7200, + }); logger.log("✅ Lido contracts deployed."); logger.log("🚀 Deploying CSM contracts..."); diff --git a/src/commands/stands/pectra-only-contracts.ts b/src/commands/stands/pectra-only-contracts.ts index 33f4e1b3..134dd3af 100644 --- a/src/commands/stands/pectra-only-contracts.ts +++ b/src/commands/stands/pectra-only-contracts.ts @@ -34,7 +34,20 @@ export const PectraContractsOnlyDevNetUp = command.cli({ const deployArgs = { verify: params.verify }; logger.log("🚀 Deploying Lido Core contracts..."); - await dre.runCommand(DeployLidoContracts, deployArgs); + await dre.runCommand(DeployLidoContracts, { + ...deployArgs, + configFile: dre.services.lidoCore.config.constants.NETWORK_STATE_DEFAULTS_FILE, + normalizedClRewardPerEpoch: 64, + normalizedClRewardMistakeRateBp: 1000, + rebaseCheckNearestEpochDistance: 1, + rebaseCheckDistantEpochDistance: 2, + validatorDelayedTimeoutInSlots: 7200, + validatorDelinquentTimeoutInSlots: 28_800, + nodeOperatorNetworkPenetrationThresholdBp: 100, + predictionDurationInSlots: 50_400, + finalizationMaxNegativeRebaseEpochShift: 1350, + exitEventsLookbackWindowInSlots: 7200, + }); logger.log("✅ Lido contracts deployed."); logger.log("🚀 Deploying CSM contracts..."); diff --git a/src/commands/stands/pectra-tw.ts b/src/commands/stands/pectra-tw.ts index a204f69e..3a9e155f 100644 --- a/src/commands/stands/pectra-tw.ts +++ b/src/commands/stands/pectra-tw.ts @@ -5,8 +5,7 @@ import { DeployTWContracts } from "../lido-core/deploy-tw.js"; import { PectraDevNetUp } from "./pectra.js"; export const PectraTWDevNetUp = command.cli({ - description: - "Triggerable Withdrawals test stand.", + description: "Triggerable Withdrawals test stand.", params: { verify: Params.boolean({ description: "Enables verification of smart contracts during deployment.", @@ -28,7 +27,10 @@ export const PectraTWDevNetUp = command.cli({ ref: "feat/tw-deploy", }); - await dre.runCommand(DeployTWContracts, {}); + await dre.runCommand(DeployTWContracts, { + configFile: + dre.services.lidoCore.config.constants.NETWORK_STATE_DEFAULTS_FILE, + }); logger.log(""); logger.log( diff --git a/src/commands/stands/pectra.ts b/src/commands/stands/pectra.ts index ac33bff0..9b88aa95 100644 --- a/src/commands/stands/pectra.ts +++ b/src/commands/stands/pectra.ts @@ -57,7 +57,20 @@ export const PectraDevNetUp = command.cli({ const depositArgs = { dsm: params.dsm }; logger.log("🚀 Deploying Lido Core contracts..."); - await dre.runCommand(DeployLidoContracts, deployArgs); + await dre.runCommand(DeployLidoContracts, { + ...deployArgs, + configFile: dre.services.lidoCore.config.constants.NETWORK_STATE_DEFAULTS_FILE, + normalizedClRewardPerEpoch: 64, + normalizedClRewardMistakeRateBp: 1000, + rebaseCheckNearestEpochDistance: 1, + rebaseCheckDistantEpochDistance: 2, + validatorDelayedTimeoutInSlots: 7200, + validatorDelinquentTimeoutInSlots: 28_800, + nodeOperatorNetworkPenetrationThresholdBp: 100, + predictionDurationInSlots: 50_400, + finalizationMaxNegativeRebaseEpochShift: 1350, + exitEventsLookbackWindowInSlots: 7200, + }); logger.log("✅ Lido contracts deployed."); logger.log("🚀 Deploying CSM contracts..."); diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo index ea4ff322..8392eb6b 100644 --- a/tsconfig.tsbuildinfo +++ b/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/commands/config.ts","./src/commands/down-offchain.ts","./src/commands/down.ts","./src/commands/wallet.ts","./src/commands/assertoor/down.ts","./src/commands/assertoor/info.ts","./src/commands/assertoor/up.ts","./src/commands/blockscout/down.ts","./src/commands/blockscout/info.ts","./src/commands/blockscout/restart.ts","./src/commands/blockscout/up.ts","./src/commands/blockscout/constants/blockscout.constants.ts","./src/commands/blockscout/extensions/blockscout.extension.ts","./src/commands/chain/chain-sync-nodes-state-from-k8s.ts","./src/commands/chain/chain-sync-state.ts","./src/commands/chain/down.ts","./src/commands/chain/fork.ts","./src/commands/chain/info.ts","./src/commands/chain/up.ts","./src/commands/chain/constants/nodes-ingress.constants.ts","./src/commands/chain/extensions/nodes-ingress.extension.ts","./src/commands/chain/extensions/nodes.extension.ts","./src/commands/council-k8s/build.ts","./src/commands/council-k8s/down.ts","./src/commands/council-k8s/up.ts","./src/commands/council-k8s/constants/council-k8s.constants.ts","./src/commands/council-k8s/extensions/council-k8s.extension.ts","./src/commands/csm/activate.ts","./src/commands/csm/add-operator.ts","./src/commands/csm/add-verifier.ts","./src/commands/csm/deploy.ts","./src/commands/csm/install.ts","./src/commands/csm/update-state.ts","./src/commands/csm/extensions/csm.extension.ts","./src/commands/csm-prover-tool-k8s/build.ts","./src/commands/csm-prover-tool-k8s/down.ts","./src/commands/csm-prover-tool-k8s/up.ts","./src/commands/csm-prover-tool-k8s/constants/csm-prover-tool-k8s.constants.ts","./src/commands/csm-prover-tool-k8s/extensions/csm-prover-tool-k8s.extension.ts","./src/commands/data-bus/deploy.ts","./src/commands/data-bus/install.ts","./src/commands/data-bus/update-state.ts","./src/commands/docker-registry/down.ts","./src/commands/docker-registry/info.ts","./src/commands/docker-registry/push-pull-secret-to-k8s.ts","./src/commands/docker-registry/up.ts","./src/commands/docker-registry/constants/docker-registry.constants.ts","./src/commands/docker-registry/extensions/docker-registry.extension.ts","./src/commands/docker-registry/templates/registry-auth-secret.template.ts","./src/commands/docker-registry/templates/registry-pull-secret.template.ts","./src/commands/dora/extensions/dora.extension.ts","./src/commands/dsm-bots-k8s/build.ts","./src/commands/dsm-bots-k8s/down.ts","./src/commands/dsm-bots-k8s/up.ts","./src/commands/dsm-bots-k8s/constants/dsm-bots-k8s.constants.ts","./src/commands/dsm-bots-k8s/extensions/dsm-bots-k8s.extension.ts","./src/commands/git/checkout.ts","./src/commands/git/pull.ts","./src/commands/k8s/ping.ts","./src/commands/k8s/set-default-context.ts","./src/commands/k8s/extensions/k8s.extension.ts","./src/commands/kapi-k8s/build.ts","./src/commands/kapi-k8s/down.ts","./src/commands/kapi-k8s/up.ts","./src/commands/kapi-k8s/constants/kapi-k8s.constants.ts","./src/commands/kapi-k8s/extensions/kapi-k8s.extension.ts","./src/commands/kubo-k8s/build.ts","./src/commands/kubo-k8s/down.ts","./src/commands/kubo-k8s/up.ts","./src/commands/kubo-k8s/constants/kubo-k8s.constants.ts","./src/commands/kubo-k8s/extensions/kubo-k8s.extension.ts","./src/commands/kurtosis/download-artifacts.ts","./src/commands/kurtosis/get-cluster-info.ts","./src/commands/kurtosis/restart-service.ts","./src/commands/kurtosis/run-package.ts","./src/commands/kurtosis/stop-package.ts","./src/commands/kurtosis/dora/down.ts","./src/commands/kurtosis/dora/info.ts","./src/commands/kurtosis/dora/up.ts","./src/commands/kurtosis/dora/constants/dora.constants.ts","./src/commands/kurtosis/dora/templates/dora-ingress.template.ts","./src/commands/kurtosis/extensions/kurtosis.extension.ts","./src/commands/kurtosis/nodes/ingress-down.ts","./src/commands/kurtosis/nodes/ingress-up.ts","./src/commands/kurtosis/nodes/templates/consensus-ingress.template.ts","./src/commands/kurtosis/nodes/templates/execution-ingress.template.ts","./src/commands/kurtosis/nodes/templates/validator-client-ingress.template.ts","./src/commands/late-prover-bot-k8s/build.ts","./src/commands/late-prover-bot-k8s/down.ts","./src/commands/late-prover-bot-k8s/up.ts","./src/commands/late-prover-bot-k8s/constants/late-prover-bot-k8s.constants.ts","./src/commands/late-prover-bot-k8s/extensions/late-prover-bot-k8s.extension.ts","./src/commands/lido-cli/install.ts","./src/commands/lido-core/activate.ts","./src/commands/lido-core/add-keys.ts","./src/commands/lido-core/add-new-operator.ts","./src/commands/lido-core/add-operator.ts","./src/commands/lido-core/deploy-tw.ts","./src/commands/lido-core/deploy.ts","./src/commands/lido-core/deposit.ts","./src/commands/lido-core/install.ts","./src/commands/lido-core/prepare-repository.ts","./src/commands/lido-core/replace-dsm.ts","./src/commands/lido-core/set-staking-limit.ts","./src/commands/lido-core/update-state.ts","./src/commands/lido-core/verify.ts","./src/commands/lido-core/extensions/lido-core.extension.ts","./src/commands/lido-core/keys/generate.ts","./src/commands/lido-core/keys/use.ts","./src/commands/no-widget/build.ts","./src/commands/no-widget/down.ts","./src/commands/no-widget/up.ts","./src/commands/no-widget/constants/no-widget.constants.ts","./src/commands/no-widget/extensions/no-widget.extension.ts","./src/commands/no-widget-backend/build.ts","./src/commands/no-widget-backend/down.ts","./src/commands/no-widget-backend/up.ts","./src/commands/no-widget-backend/constants/no-widget-backend.constants.ts","./src/commands/no-widget-backend/extensions/no-widget-backend.extension.ts","./src/commands/oracles-k8s/build.ts","./src/commands/oracles-k8s/down.ts","./src/commands/oracles-k8s/up.ts","./src/commands/oracles-k8s/constants/oracles-k8s.constants.ts","./src/commands/oracles-k8s/extensions/oracles-k8s.extension.ts","./src/commands/ssh/tunnel.ts","./src/commands/stands/csm-v2.ts","./src/commands/stands/fusaka-zk-test.ts","./src/commands/stands/fusaka.ts","./src/commands/stands/pectra-only-chain.ts","./src/commands/stands/pectra-only-contracts.ts","./src/commands/stands/pectra-tw.ts","./src/commands/stands/pectra.ts","./src/commands/system/docs.ts","./src/commands/system/server.ts","./src/commands/validator/add.ts","./src/commands/validator/list.ts","./src/commands/validator/remove.ts","./src/commands/validator/restart.ts","./src/commands/validator/voluntary-exit.ts","./src/commands/validator/keys/generate.ts","./src/commands/validator/keys/test-generate.ts","./src/commands/voting/add-account.ts","./src/commands/voting/auto-vote.ts","./src/commands/voting/enact-after-pectra.ts","./src/commands/voting/enact-before-pectra.ts","./src/commands/voting/enact-tw.ts","./src/commands/voting/install.ts","./src/commands/voting/prepare-pectra.ts"],"version":"5.7.3"} \ No newline at end of file +{"root":["./src/commands/config.ts","./src/commands/down-offchain.ts","./src/commands/down.ts","./src/commands/wallet.ts","./src/commands/assertoor/down.ts","./src/commands/assertoor/info.ts","./src/commands/assertoor/up.ts","./src/commands/blockscout/down.ts","./src/commands/blockscout/info.ts","./src/commands/blockscout/restart.ts","./src/commands/blockscout/up.ts","./src/commands/blockscout/constants/blockscout.constants.ts","./src/commands/blockscout/extensions/blockscout.extension.ts","./src/commands/chain/chain-sync-nodes-state-from-k8s.ts","./src/commands/chain/chain-sync-state.ts","./src/commands/chain/down.ts","./src/commands/chain/fork.ts","./src/commands/chain/info.ts","./src/commands/chain/up.ts","./src/commands/chain/constants/nodes-ingress.constants.ts","./src/commands/chain/extensions/nodes-ingress.extension.ts","./src/commands/chain/extensions/nodes.extension.ts","./src/commands/council-k8s/build.ts","./src/commands/council-k8s/down.ts","./src/commands/council-k8s/up.ts","./src/commands/council-k8s/constants/council-k8s.constants.ts","./src/commands/council-k8s/extensions/council-k8s.extension.ts","./src/commands/csm/activate.ts","./src/commands/csm/add-operator.ts","./src/commands/csm/add-verifier.ts","./src/commands/csm/deploy.ts","./src/commands/csm/install.ts","./src/commands/csm/update-state.ts","./src/commands/csm/extensions/csm.extension.ts","./src/commands/csm-prover-tool-k8s/build.ts","./src/commands/csm-prover-tool-k8s/down.ts","./src/commands/csm-prover-tool-k8s/up.ts","./src/commands/csm-prover-tool-k8s/constants/csm-prover-tool-k8s.constants.ts","./src/commands/csm-prover-tool-k8s/extensions/csm-prover-tool-k8s.extension.ts","./src/commands/data-bus/deploy.ts","./src/commands/data-bus/install.ts","./src/commands/data-bus/update-state.ts","./src/commands/docker-registry/down.ts","./src/commands/docker-registry/info.ts","./src/commands/docker-registry/push-pull-secret-to-k8s.ts","./src/commands/docker-registry/up.ts","./src/commands/docker-registry/constants/docker-registry.constants.ts","./src/commands/docker-registry/extensions/docker-registry.extension.ts","./src/commands/docker-registry/templates/registry-auth-secret.template.ts","./src/commands/docker-registry/templates/registry-pull-secret.template.ts","./src/commands/dora/extensions/dora.extension.ts","./src/commands/dsm-bots-k8s/build.ts","./src/commands/dsm-bots-k8s/down.ts","./src/commands/dsm-bots-k8s/up.ts","./src/commands/dsm-bots-k8s/constants/dsm-bots-k8s.constants.ts","./src/commands/dsm-bots-k8s/extensions/dsm-bots-k8s.extension.ts","./src/commands/git/checkout.ts","./src/commands/git/pull.ts","./src/commands/k8s/ping.ts","./src/commands/k8s/set-default-context.ts","./src/commands/k8s/extensions/k8s.extension.ts","./src/commands/kapi-k8s/build.ts","./src/commands/kapi-k8s/down.ts","./src/commands/kapi-k8s/up.ts","./src/commands/kapi-k8s/constants/kapi-k8s.constants.ts","./src/commands/kapi-k8s/extensions/kapi-k8s.extension.ts","./src/commands/kubo-k8s/build.ts","./src/commands/kubo-k8s/down.ts","./src/commands/kubo-k8s/up.ts","./src/commands/kubo-k8s/constants/kubo-k8s.constants.ts","./src/commands/kubo-k8s/extensions/kubo-k8s.extension.ts","./src/commands/kurtosis/download-artifacts.ts","./src/commands/kurtosis/get-cluster-info.ts","./src/commands/kurtosis/restart-service.ts","./src/commands/kurtosis/run-package.ts","./src/commands/kurtosis/stop-package.ts","./src/commands/kurtosis/dora/down.ts","./src/commands/kurtosis/dora/info.ts","./src/commands/kurtosis/dora/up.ts","./src/commands/kurtosis/dora/constants/dora.constants.ts","./src/commands/kurtosis/dora/templates/dora-ingress.template.ts","./src/commands/kurtosis/extensions/kurtosis.extension.ts","./src/commands/kurtosis/nodes/ingress-down.ts","./src/commands/kurtosis/nodes/ingress-up.ts","./src/commands/kurtosis/nodes/templates/consensus-ingress.template.ts","./src/commands/kurtosis/nodes/templates/execution-ingress.template.ts","./src/commands/kurtosis/nodes/templates/validator-client-ingress.template.ts","./src/commands/late-prover-bot-k8s/build.ts","./src/commands/late-prover-bot-k8s/down.ts","./src/commands/late-prover-bot-k8s/up.ts","./src/commands/late-prover-bot-k8s/constants/late-prover-bot-k8s.constants.ts","./src/commands/late-prover-bot-k8s/extensions/late-prover-bot-k8s.extension.ts","./src/commands/lido-cli/install.ts","./src/commands/lido-core/activate.ts","./src/commands/lido-core/add-keys.ts","./src/commands/lido-core/add-new-operator.ts","./src/commands/lido-core/add-operator.ts","./src/commands/lido-core/deploy-tw.ts","./src/commands/lido-core/deploy.ts","./src/commands/lido-core/deposit.ts","./src/commands/lido-core/install.ts","./src/commands/lido-core/prepare-repository.ts","./src/commands/lido-core/replace-dsm.ts","./src/commands/lido-core/set-staking-limit.ts","./src/commands/lido-core/update-state.ts","./src/commands/lido-core/verify.ts","./src/commands/lido-core/extensions/lido-core.extension.ts","./src/commands/lido-core/keys/generate.ts","./src/commands/lido-core/keys/use.ts","./src/commands/no-widget/build.ts","./src/commands/no-widget/down.ts","./src/commands/no-widget/up.ts","./src/commands/no-widget/constants/no-widget.constants.ts","./src/commands/no-widget/extensions/no-widget.extension.ts","./src/commands/no-widget-backend/build.ts","./src/commands/no-widget-backend/down.ts","./src/commands/no-widget-backend/up.ts","./src/commands/no-widget-backend/constants/no-widget-backend.constants.ts","./src/commands/no-widget-backend/extensions/no-widget-backend.extension.ts","./src/commands/oracles-k8s/build.ts","./src/commands/oracles-k8s/down.ts","./src/commands/oracles-k8s/up.ts","./src/commands/oracles-k8s/constants/oracles-k8s.constants.ts","./src/commands/oracles-k8s/extensions/oracles-k8s.extension.ts","./src/commands/ssh/tunnel.ts","./src/commands/stands/csm-v2.ts","./src/commands/stands/fusaka-zk-test.ts","./src/commands/stands/fusaka.ts","./src/commands/stands/pectra-only-chain.ts","./src/commands/stands/pectra-only-contracts.ts","./src/commands/stands/pectra-tw.ts","./src/commands/stands/pectra.ts","./src/commands/system/docs.ts","./src/commands/system/server.ts","./src/commands/validator/add.ts","./src/commands/validator/list.ts","./src/commands/validator/remove.ts","./src/commands/validator/restart.ts","./src/commands/validator/voluntary-exit.ts","./src/commands/validator/keys/generate.ts","./src/commands/validator/keys/test-generate.ts","./src/commands/voting/add-account.ts","./src/commands/voting/auto-vote.ts","./src/commands/voting/enact-after-pectra.ts","./src/commands/voting/enact-before-pectra.ts","./src/commands/voting/enact-tw.ts","./src/commands/voting/install.ts","./src/commands/voting/prepare-pectra.ts"],"version":"5.7.3"} diff --git a/workspaces/genesis-generator/Makefile b/workspaces/genesis-generator/Makefile new file mode 100644 index 00000000..88bb6a1e --- /dev/null +++ b/workspaces/genesis-generator/Makefile @@ -0,0 +1,93 @@ +# Makefile for Helm Operations +# This Makefile provides convenient commands for managing Helm charts + +# Default namespace for Helm operations +NAMESPACE ?= test-namespace + +# Helm chart paths +HELM_CHART_ROOT_PATH ?= ../../helm +HELM_CHART_PATH = $(HELM_CHART_ROOT_PATH)/lido/lido-genesis-generator +HELM_VALUES_PATH = ./values.yaml + +# Release names +HELM_RELEASE = genesis-generator + +# Default Helm timeout +TIMEOUT ?= 5m + +# Default Helm flags +HELM_DEBUG ?= true +ifeq ($(HELM_DEBUG), true) + HELM_DEBUG_FLAG = --debug +else + HELM_DEBUG_FLAG = +endif + +# Default values for chart versions (empty means latest) +HELM_CHART_VERSION ?= + +# Version flags (only add if version is specified) +ifneq ($(HELM_CHART_VERSION),) + HELM_VERSION_FLAG = --version $(HELM_CHART_VERSION) +else + HELM_VERSION_FLAG = +endif + +define HELM_CHART_VALUES_OVERRIDES + --set lido-app.env.variables="$(DOCKER_REGISTRY_INGRESS_HOSTNAME)" +endef + +# Lint Helm chart +.PHONY: debug +debug: + echo "\n" \ + echo ${pwd} \ + echo "HELM_CHART_PATH=[$(HELM_CHART_PATH)]\n" && \ + echo "HELM_VALUES_PATH=[$(HELM_VALUES_PATH)]\n" && \ + echo "HELM_CHART_VALUES_OVERRIDES=[$(HELM_CHART_VALUES_OVERRIDES)]\n" + +# Lint Helm chart +.PHONY: lint +lint: + helm lint $(HELM_CHART_PATH) -f $(HELM_VALUES_PATH) $(HELM_CHART_VALUES_OVERRIDES) + +# Print rendered Helm chart templates to stdout +.PHONY: template +template: + helm template $(HELM_RELEASE) $(HELM_CHART_PATH) -f $(HELM_VALUES_PATH) --namespace $(NAMESPACE) \ + $(HELM_CHART_VALUES_OVERRIDES) $(HELM_DEBUG_FLAG) + +# Dry-run Helm chart install into K8s +.PHONY: dry-run +dry-run: + helm template $(HELM_RELEASE) $(HELM_CHART_PATH) -f $(HELM_VALUES_PATH) --namespace $(NAMESPACE) \ + $(HELM_CHART_VALUES_OVERRIDES) \ + | kubectl apply --dry-run=client -f - + +# Helm chart install into K8s +.PHONY: install +install: + helm install $(HELM_RELEASE) $(HELM_CHART_PATH) \ + -f $(HELM_VALUES_PATH) \ + $(HELM_CHART_VALUES_OVERRIDES) \ + --namespace $(NAMESPACE) \ + --create-namespace \ + --timeout $(TIMEOUT) \ + $(HELM_VERSION_FLAG) \ + $(HELM_DEBUG_FLAG) + +# Helm chart upgrade existing installation +.PHONY: upgrade +upgrade: + helm upgrade $(HELM_RELEASE) $(HELM_CHART_PATH) \ + -f $(HELM_VALUES_PATH) \ + $(HELM_CHART_VALUES_OVERRIDES) \ + --namespace $(NAMESPACE) \ + --timeout $(TIMEOUT) \ + $(HELM_VERSION_FLAG) \ + $(HELM_DEBUG_FLAG) + +# Helm chart uninstall +.PHONY: uninstall +uninstall: + helm uninstall $(HELM_RELEASE) --namespace $(NAMESPACE) --ignore-not-found diff --git a/workspaces/kurtosis/fusaka-devnet2.yml b/workspaces/kurtosis/fusaka-devnet2.yml index c8c16f9f..b6401947 100644 --- a/workspaces/kurtosis/fusaka-devnet2.yml +++ b/workspaces/kurtosis/fusaka-devnet2.yml @@ -1,7 +1,6 @@ participants: - - el_type: geth - el_image: ethereum/client-go:v1.16.4 + el_image: ethereum/client-go:v1.16.5 el_extra_params: [ --syncmode=full --rpc.allow-unprotected-txs --gcmode=archive ] el_min_cpu: 0 el_max_cpu: 0 @@ -19,28 +18,27 @@ participants: cl_min_cpu: 4000 cl_max_cpu: 8000 cl_min_mem: 16384 - cl_max_mem: 32768 cl_volume_size: 51200 count: 1 - - el_type: erigon - el_image: erigontech/erigon:v3.2.0-rc1 - el_extra_params: [ --prune.mode=archive ] - el_min_cpu: 0 - el_max_cpu: 0 - el_min_mem: 0 - el_max_mem: 0 - el_volume_size: 51200 - # CL - cl_type: lighthouse - cl_image: sigp/lighthouse:v8.0.0-rc.1 - cl_extra_params: [ '--hierarchy-exponents=5,7,11', --reconstruct-historic-states ] - supernode: true - cl_volume_size: 51200 - count: 1 + # - el_type: erigon + # el_image: erigontech/erigon:v3.2.1 + # el_extra_params: [ --prune.mode=archive ] + # el_min_cpu: 0 + # el_max_cpu: 0 + # el_min_mem: 0 + # el_max_mem: 0 + # el_volume_size: 51200 + # # CL + # cl_type: lighthouse + # cl_image: sigp/lighthouse:v8.0.0-rc.2 + # cl_extra_params: [ '--hierarchy-exponents=5,7,11', --reconstruct-historic-states ] + # supernode: true + # cl_volume_size: 51200 + # count: 1 - el_type: geth - el_image: ethereum/client-go:v1.16.4 + el_image: ethereum/client-go:v1.16.5 el_extra_params: [ --rpc.gascap=16777215 --syncmode=full --rpc.allow-unprotected-txs --gcmode=archive ] el_min_cpu: 0 el_max_cpu: 0 @@ -49,7 +47,7 @@ participants: el_volume_size: 51200 # CL cl_type: lighthouse - cl_image: sigp/lighthouse:v8.0.0-rc.1 + cl_image: sigp/lighthouse:v8.0.0-rc.2 cl_extra_params: [ '--hierarchy-exponents=5,7,11', --reconstruct-historic-states ] supernode: true cl_volume_size: 51200 @@ -75,6 +73,9 @@ network_params: bpo_5_target_blobs: 6 withdrawal_type: "0x02" preset: mainnet + validator_balance: 2048 + num_validator_keys_per_node: 5000 + shard_committee_period: 1 persistent: true diff --git a/workspaces/network/services/geth.yml b/workspaces/network/services/geth.yml index d9e15d1e..c215a648 100644 --- a/workspaces/network/services/geth.yml +++ b/workspaces/network/services/geth.yml @@ -30,7 +30,7 @@ services: - --unlock=0x123463a4b065722e99115d6c222f267d9cabb524 - --password=/opt/geth_password.txt - --nodiscover - - --syncmode=full + - --syncmode=archive - --state.scheme=hash ports: - 8551:8551 diff --git a/yarn.lock b/yarn.lock index 514875c9..88dbf660 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1128,6 +1128,7 @@ __metadata: "@devnet/utils": "workspace:*" "@fastify/swagger": "npm:^9.4.2" "@fastify/swagger-ui": "npm:^5.2.1" + "@iarna/toml": "npm:^2.2.5" "@oclif/core": "npm:^4.0.37" "@oclif/plugin-help": "npm:^6.2.19" "@types/node": "npm:^22.10.5" @@ -1420,6 +1421,13 @@ __metadata: languageName: node linkType: hard +"@iarna/toml@npm:^2.2.5": + version: 2.2.5 + resolution: "@iarna/toml@npm:2.2.5" + checksum: 10c0/d095381ad4554aca233b7cf5a91f243ef619e5e15efd3157bc640feac320545450d14b394aebbf6f02a2047437ced778ae598d5879a995441ab7b6c0b2c2f201 + languageName: node + linkType: hard + "@inquirer/checkbox@npm:^4.1.2": version: 4.1.2 resolution: "@inquirer/checkbox@npm:4.1.2"