mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 01:38:32 +00:00
fix: 🐛 CLI fixes for independently running parts of it (#85)
This commit is contained in:
parent
d79f727949
commit
c29fc8f06d
9 changed files with 128 additions and 95 deletions
|
|
@ -4,7 +4,7 @@ fullnameOverride: dh-bootnode
|
|||
|
||||
image:
|
||||
repository: moonsonglabs/datahaven
|
||||
tag: pr-78
|
||||
tag: main
|
||||
pullPolicy: Always
|
||||
|
||||
imagePullSecrets:
|
||||
|
|
@ -38,7 +38,7 @@ extraInitContainers:
|
|||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
command: [ "/bin/bash" ]
|
||||
command: ["/bin/bash"]
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
|
|
@ -63,4 +63,4 @@ extraContainers:
|
|||
- name: chain-data
|
||||
subPath: chainspec.json
|
||||
mountPath: /usr/share/nginx/html/chainspec.json
|
||||
readOnly: true
|
||||
readOnly: true
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ fullnameOverride: dh-validator
|
|||
|
||||
image:
|
||||
repository: moonsonglabs/datahaven
|
||||
tag: pr-78
|
||||
tag: main
|
||||
pullPolicy: Always
|
||||
|
||||
imagePullSecrets:
|
||||
|
|
@ -23,7 +23,7 @@ node:
|
|||
chainKeystore:
|
||||
storageClass: "gp2"
|
||||
keys:
|
||||
# This is Alice seed. To generate new seed run: docker run --rm moonsonglabs/datahaven:latest key generate
|
||||
# This is Alice seed. To generate new seed run: docker run --rm moonsonglabs/datahaven:latest key generate
|
||||
- seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk"
|
||||
type: gran
|
||||
scheme: ed25519
|
||||
|
|
@ -42,11 +42,11 @@ node:
|
|||
scheme: ecdsa
|
||||
extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")'
|
||||
customNodeKey:
|
||||
# To generate new key run: docker run --rm -t moonsonglabs/datahaven:latest key generate-node-key
|
||||
# 12D3KooWL5Av1ZZSKkaittmxXBmZpzP7zgiB1AAnWHEw7MxzqnFp
|
||||
- bdf71a910354e231095366230621eaefb5f99465045f1501478fd3d9b5deef98
|
||||
# 12D3KooWAxFonTS177T81CTDeH6mfvJQWYEJeVQ1gPrnULjNY8Cn
|
||||
- 2a775a9db9fb0ff40afacb4aa7ccbf2a5d04c6d980bb1437c196c8e38a6cd948
|
||||
# To generate new key run: docker run --rm -t moonsonglabs/datahaven:latest key generate-node-key
|
||||
# 12D3KooWL5Av1ZZSKkaittmxXBmZpzP7zgiB1AAnWHEw7MxzqnFp
|
||||
- bdf71a910354e231095366230621eaefb5f99465045f1501478fd3d9b5deef98
|
||||
# 12D3KooWAxFonTS177T81CTDeH6mfvJQWYEJeVQ1gPrnULjNY8Cn
|
||||
- 2a775a9db9fb0ff40afacb4aa7ccbf2a5d04c6d980bb1437c196c8e38a6cd948
|
||||
flags:
|
||||
- "--bootnodes /dns/dh-bootnode-0/tcp/30333/p2p/12D3KooWRpzRTivvJ5ySvgbFnPeEE6rDhitQKL1fFJvvBGhnenSk"
|
||||
enableOffchainIndexing: true
|
||||
|
|
@ -61,7 +61,7 @@ extraInitContainers:
|
|||
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
command: [ "/bin/bash" ]
|
||||
command: ["/bin/bash"]
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
|
|
|
|||
|
|
@ -66,38 +66,6 @@ export const launchDataHavenSolochain = async (
|
|||
|
||||
let shouldLaunchDataHaven = options.datahaven;
|
||||
|
||||
if ((await checkDataHavenRunning()) && !options.alwaysClean) {
|
||||
logger.info("ℹ️ DataHaven network (Docker containers) is already running.");
|
||||
|
||||
logger.trace("Checking if datahaven option was set via flags");
|
||||
if (options.datahaven === false) {
|
||||
logger.info("Keeping existing DataHaven containers.");
|
||||
|
||||
await registerNodes(launchedNetwork);
|
||||
printDivider();
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.datahaven === true) {
|
||||
await cleanDataHavenContainers(options);
|
||||
} else {
|
||||
const shouldRelaunch = await confirmWithTimeout(
|
||||
"Do you want to clean and relaunch the DataHaven containers?",
|
||||
true,
|
||||
10
|
||||
);
|
||||
|
||||
if (!shouldRelaunch) {
|
||||
logger.info("Keeping existing DataHaven containers.");
|
||||
|
||||
await registerNodes(launchedNetwork);
|
||||
printDivider();
|
||||
return;
|
||||
}
|
||||
await cleanDataHavenContainers(options);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldLaunchDataHaven === undefined) {
|
||||
shouldLaunchDataHaven = await confirmWithTimeout(
|
||||
"Do you want to launch the DataHaven network?",
|
||||
|
|
@ -111,11 +79,42 @@ export const launchDataHavenSolochain = async (
|
|||
}
|
||||
|
||||
if (!shouldLaunchDataHaven) {
|
||||
logger.info("Skipping DataHaven network launch. Done!");
|
||||
logger.info("👍 Skipping DataHaven network launch. Done!");
|
||||
|
||||
await registerNodes(launchedNetwork);
|
||||
printDivider();
|
||||
return;
|
||||
}
|
||||
|
||||
if (await checkDataHavenRunning()) {
|
||||
// If the user wants to launch the DataHaven network, we ask them if they want
|
||||
// to clean the existing containers/network or just continue with the existing
|
||||
// containers/network.
|
||||
if (shouldLaunchDataHaven) {
|
||||
let shouldRelaunch = options.cleanNetwork;
|
||||
|
||||
if (shouldRelaunch === undefined) {
|
||||
shouldRelaunch = await confirmWithTimeout(
|
||||
"Do you want to clean and relaunch the DataHaven containers?",
|
||||
true,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
// Case: User wants to keep existing containers/network
|
||||
if (!shouldRelaunch) {
|
||||
logger.info("👍 Keeping existing DataHaven containers/network.");
|
||||
|
||||
await registerNodes(launchedNetwork);
|
||||
printDivider();
|
||||
return;
|
||||
}
|
||||
|
||||
// Case: User wants to clean and relaunch the DataHaven containers
|
||||
await cleanDataHavenContainers(options);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`⛓️💥 Creating Docker network: ${DOCKER_NETWORK_NAME}`);
|
||||
logger.debug(await $`docker network rm ${DOCKER_NETWORK_NAME} -f`.text());
|
||||
logger.debug(await $`docker network create ${DOCKER_NETWORK_NAME}`.text());
|
||||
|
|
@ -125,7 +124,6 @@ export const launchDataHavenSolochain = async (
|
|||
await buildLocalImage(options);
|
||||
await checkTagExists(options.datahavenImageTag);
|
||||
|
||||
launchedNetwork.networkName = DOCKER_NETWORK_NAME;
|
||||
logger.success(`DataHaven nodes will use Docker network: ${DOCKER_NETWORK_NAME}`);
|
||||
|
||||
for (const id of CLI_AUTHORITY_IDS) {
|
||||
|
|
@ -191,18 +189,25 @@ export const launchDataHavenSolochain = async (
|
|||
*/
|
||||
const checkDataHavenRunning = async (): Promise<boolean> => {
|
||||
// Check for any container whose name starts with "datahaven-"
|
||||
const containerIds = await $`docker ps -q --filter "name=^datahaven-"`.text();
|
||||
const containerIds = await $`docker ps --format "{{.Names}}" --filter "name=^datahaven-"`.text();
|
||||
const networkOutput =
|
||||
await $`docker network ls --filter "name=^${DOCKER_NETWORK_NAME}$" --format "{{.Name}}"`.text();
|
||||
|
||||
// Check if containerIds has any actual IDs (not just whitespace)
|
||||
const containersExist = containerIds.trim().length > 0;
|
||||
if (containersExist) {
|
||||
logger.info(`ℹ️ DataHaven containers already running: \n${containerIds}`);
|
||||
}
|
||||
|
||||
// Check if networkOutput has any network names (not just whitespace or empty lines)
|
||||
const networksExist =
|
||||
networkOutput
|
||||
.trim()
|
||||
.split("\n")
|
||||
.filter((line) => line.trim().length > 0).length > 0;
|
||||
if (networksExist) {
|
||||
logger.info(`ℹ️ DataHaven network already running: ${networkOutput}`);
|
||||
}
|
||||
|
||||
return containersExist || networksExist;
|
||||
};
|
||||
|
|
@ -227,6 +232,11 @@ const cleanDataHavenContainers = async (options: LaunchOptions): Promise<void> =
|
|||
|
||||
logger.debug(await $`docker network rm -f ${DOCKER_NETWORK_NAME}`.text());
|
||||
logger.info("✅ DataHaven Docker network removed.");
|
||||
|
||||
invariant(
|
||||
(await checkDataHavenRunning()) === false,
|
||||
"❌ DataHaven containers were not stopped and removed"
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -309,6 +319,9 @@ const checkTagExists = async (tag: string) => {
|
|||
};
|
||||
|
||||
const registerNodes = async (launchedNetwork: LaunchedNetwork) => {
|
||||
// Registering DataHaven nodes Docker network.
|
||||
launchedNetwork.networkName = DOCKER_NETWORK_NAME;
|
||||
|
||||
const targetContainerName = "datahaven-alice";
|
||||
const aliceHostWsPort = 9944; // Standard host port for Alice's WS, as set during launch.
|
||||
|
||||
|
|
@ -319,9 +332,8 @@ const registerNodes = async (launchedNetwork: LaunchedNetwork) => {
|
|||
|
||||
if (!isContainerRunning) {
|
||||
// If the target Docker container is not running, we cannot register it.
|
||||
throw new Error(
|
||||
`❌ Docker container ${targetContainerName} is not running. Cannot register node.`
|
||||
);
|
||||
logger.warn(`⚠️ Docker container ${targetContainerName} is not running. Cannot register node.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the Docker container is running, proceed to register it in launchedNetwork.
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ export interface LaunchOptions {
|
|||
blockscout?: boolean;
|
||||
relayer?: boolean;
|
||||
relayerImageTag?: string;
|
||||
skipCleaning?: boolean;
|
||||
alwaysClean?: boolean;
|
||||
cleanNetwork?: boolean;
|
||||
datahaven?: boolean;
|
||||
buildDatahaven?: boolean;
|
||||
datahavenImageTag?: string;
|
||||
|
|
|
|||
|
|
@ -15,27 +15,43 @@ export const launchKurtosis = async (
|
|||
launchedNetwork: LaunchedNetwork,
|
||||
options: LaunchOptions = {}
|
||||
): Promise<void> => {
|
||||
printHeader("Starting Kurtosis Network");
|
||||
printHeader("Starting Kurtosis EthereumNetwork");
|
||||
|
||||
if ((await checkKurtosisRunning()) && !options.alwaysClean) {
|
||||
logger.info("ℹ️ Kurtosis network is already running.");
|
||||
let shouldLaunchKurtosis = options.launchKurtosis;
|
||||
|
||||
logger.trace("Checking if launchKurtosis option was set via flags");
|
||||
if (options.launchKurtosis === false) {
|
||||
logger.info("👍 Keeping existing Kurtosis enclave.");
|
||||
if (shouldLaunchKurtosis === undefined) {
|
||||
shouldLaunchKurtosis = await confirmWithTimeout(
|
||||
"Do you want to launch the Kurtosis network?",
|
||||
true,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
await registerServices(launchedNetwork);
|
||||
printDivider();
|
||||
return;
|
||||
}
|
||||
if (!shouldLaunchKurtosis) {
|
||||
logger.info("👍 Skipping Kurtosis Ethereum network launch. Done!");
|
||||
|
||||
if (options.launchKurtosis !== true) {
|
||||
const shouldRelaunch = await confirmWithTimeout(
|
||||
"Do you want to clean and relaunch the Kurtosis enclave?",
|
||||
true,
|
||||
10
|
||||
);
|
||||
await registerServices(launchedNetwork);
|
||||
printDivider();
|
||||
return;
|
||||
}
|
||||
|
||||
if (await checkKurtosisRunning()) {
|
||||
logger.info("ℹ️ Kurtosis Ethereum network is already running.");
|
||||
|
||||
// If the user wants to launch the Kurtosis network, we ask them if they want
|
||||
// to clean the existing enclave or just continue with the existing enclave.
|
||||
if (shouldLaunchKurtosis) {
|
||||
let shouldRelaunch = options.cleanNetwork;
|
||||
|
||||
if (shouldRelaunch === undefined) {
|
||||
shouldRelaunch = await confirmWithTimeout(
|
||||
"Do you want to clean and relaunch the Kurtosis enclave?",
|
||||
true,
|
||||
10
|
||||
);
|
||||
}
|
||||
|
||||
// Case: User wants to keep existing enclave
|
||||
if (!shouldRelaunch) {
|
||||
logger.info("👍 Keeping existing Kurtosis enclave.");
|
||||
|
||||
|
|
@ -43,15 +59,14 @@ export const launchKurtosis = async (
|
|||
printDivider();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.skipCleaning) {
|
||||
logger.info("🧹 Cleaning up Docker and Kurtosis environments...");
|
||||
logger.debug(await $`kurtosis enclave stop datahaven-ethereum`.nothrow().text());
|
||||
logger.debug(await $`kurtosis clean`.text());
|
||||
logger.debug(await $`kurtosis engine stop`.text());
|
||||
logger.debug(await $`docker system prune -f`.nothrow().text());
|
||||
// Case: User wants to clean and relaunch the enclave
|
||||
logger.info("🧹 Cleaning up Docker and Kurtosis environments...");
|
||||
logger.debug(await $`kurtosis enclave stop datahaven-ethereum`.nothrow().text());
|
||||
logger.debug(await $`kurtosis clean`.text());
|
||||
logger.debug(await $`kurtosis engine stop`.nothrow().text());
|
||||
logger.debug(await $`docker system prune -f`.nothrow().text());
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === "darwin") {
|
||||
|
|
@ -141,19 +156,23 @@ const registerServices = async (launchedNetwork: LaunchedNetwork) => {
|
|||
logger.info("📝 Registering Kurtosis service endpoints...");
|
||||
|
||||
// Configure EL RPC URL
|
||||
const rethPublicPort = await getPortFromKurtosis("el-1-reth-lighthouse", "rpc");
|
||||
invariant(rethPublicPort && rethPublicPort > 0, "❌ Could not find EL RPC port");
|
||||
const elRpcUrl = `http://127.0.0.1:${rethPublicPort}`;
|
||||
launchedNetwork.elRpcUrl = elRpcUrl;
|
||||
logger.info(`📝 Execution Layer RPC URL configured: ${elRpcUrl}`);
|
||||
try {
|
||||
const rethPublicPort = await getPortFromKurtosis("el-1-reth-lighthouse", "rpc");
|
||||
invariant(rethPublicPort && rethPublicPort > 0, "❌ Could not find EL RPC port");
|
||||
const elRpcUrl = `http://127.0.0.1:${rethPublicPort}`;
|
||||
launchedNetwork.elRpcUrl = elRpcUrl;
|
||||
logger.info(`📝 Execution Layer RPC URL configured: ${elRpcUrl}`);
|
||||
|
||||
// Configure CL Endpoint
|
||||
const lighthousePublicPort = await getPortFromKurtosis("cl-1-lighthouse-reth", "http");
|
||||
const clEndpoint = `http://127.0.0.1:${lighthousePublicPort}`;
|
||||
invariant(
|
||||
clEndpoint,
|
||||
"❌ CL Endpoint could not be determined from Kurtosis service cl-1-lighthouse-reth"
|
||||
);
|
||||
launchedNetwork.clEndpoint = clEndpoint;
|
||||
logger.info(`📝 Consensus Layer Endpoint configured: ${clEndpoint}`);
|
||||
// Configure CL Endpoint
|
||||
const lighthousePublicPort = await getPortFromKurtosis("cl-1-lighthouse-reth", "http");
|
||||
const clEndpoint = `http://127.0.0.1:${lighthousePublicPort}`;
|
||||
invariant(
|
||||
clEndpoint,
|
||||
"❌ CL Endpoint could not be determined from Kurtosis service cl-1-lighthouse-reth"
|
||||
);
|
||||
launchedNetwork.clEndpoint = clEndpoint;
|
||||
logger.info(`📝 Consensus Layer Endpoint configured: ${clEndpoint}`);
|
||||
} catch (error) {
|
||||
logger.warn(`⚠️ Kurtosis service endpoints could not be determined: ${error}`);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ export const launchRelayers = async (options: LaunchOptions, launchedNetwork: La
|
|||
}
|
||||
|
||||
if (!shouldLaunchRelayers) {
|
||||
logger.info("Skipping Snowbridge relayers launch. Done!");
|
||||
logger.info("👍 Snowbridge relayers launch. Done!");
|
||||
printDivider();
|
||||
return;
|
||||
}
|
||||
|
|
@ -339,6 +339,10 @@ export const initEthClientPallet = async (
|
|||
logger.debug(await $`docker rm -f generate-beacon-checkpoint`.text());
|
||||
|
||||
logger.debug("Generating beacon checkpoint");
|
||||
invariant(
|
||||
launchedNetwork.networkName,
|
||||
"❌ Docker network name not found in LaunchedNetwork instance"
|
||||
);
|
||||
const command = `docker run \
|
||||
-v ${beaconConfigHostPath}:${beaconConfigContainerPath}:ro \
|
||||
-v ${checkpointHostPath}:${checkpointContainerPath} \
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ const program = new Command()
|
|||
.option("--nr, --no-relayer", "Skip Snowbridge Relayers")
|
||||
.option("--b, --blockscout", "Enable Blockscout")
|
||||
.option("--slot-time <number>", "Set slot time in seconds", parseIntValue)
|
||||
.option("--cn, --clean-network", "Always clean Kurtosis enclave and Docker containers")
|
||||
.option(
|
||||
"--datahaven-build-extra-args <value>",
|
||||
"Extra args for DataHaven node Cargo build (the plain command is `cargo build --release` for linux, `cargo zigbuild --target x86_64-unknown-linux-gnu --release` for mac)",
|
||||
|
|
@ -39,8 +40,6 @@ const program = new Command()
|
|||
)
|
||||
.option("--kurtosis-network-args <value>", "CustomKurtosis network args")
|
||||
.option("--verified", "Verify smart contracts with Blockscout")
|
||||
.option("--always-clean", "Always clean Kurtosis", false)
|
||||
.option("--skip-cleaning", "Skip cleaning Kurtosis")
|
||||
.option(
|
||||
"-i, --datahaven-image-tag <value>",
|
||||
"Tag of the datahaven image to use",
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@
|
|||
"start:e2e:verified": "bun cli --verified --blockscout --deploy-contracts --setup-validators --update-validator-set --fund-validators",
|
||||
"start:e2e:verified:relayers": "bun cli --verified --blockscout --deploy-contracts --setup-validators --update-validator-set --fund-validators --slot-time 1 --relayer --datahaven",
|
||||
"start:e2e:local": "LOG_LEVEL=debug bun start:e2e:ci --bd",
|
||||
"start:e2e:ci": "bun cli --datahaven --no-build-datahaven --launch-kurtosis --deploy-contracts --fund-validators --setup-validators --update-validator-set --relayer --always-clean",
|
||||
"start:e2e:ci": "bun cli --datahaven --no-build-datahaven --launch-kurtosis --deploy-contracts --fund-validators --setup-validators --update-validator-set --relayer --clean-network",
|
||||
"start:e2e:minrelayer": "bun cli --relayer --deploy-contracts --no-setup-validators --no-update-validator-set --no-fund-validators --datahaven",
|
||||
"stop:docker:datahaven": "docker rm -f $(docker ps -aq --filter name='^datahaven-') 2>/dev/null || true",
|
||||
"stop:docker:datahaven": "docker rm -f $(docker ps -aq --filter name='^datahaven-') 2>/dev/null || true; docker network rm datahaven-net || true",
|
||||
"stop:docker:relayer": "docker rm -f $(docker ps -aq --filter name='^snowbridge-relayer-') 2>/dev/null || true",
|
||||
"stop:e2e": "bun stop:docker:datahaven ; bun stop:docker:relayer ; (kurtosis enclave stop datahaven-ethereum || true) && kurtosis clean && kurtosis engine stop && docker container prune -f",
|
||||
"start:e2e:minimal:relayer": "bun cli --relayer --deploy-contracts --no-setup-validators --no-update-validator-set --no-fund-validators --datahaven",
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export const deployContracts = async (options: DeployContractsOptions): Promise<
|
|||
}
|
||||
|
||||
if (!shouldDeployContracts) {
|
||||
logger.info("Skipping contract deployment. Done!");
|
||||
logger.info("👍 Skipping contract deployment. Done!");
|
||||
printDivider();
|
||||
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in a new issue