diff --git a/Dockerfile b/Dockerfile index 6f8e3939d4..111a9093c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,9 +30,16 @@ COPY solidity ./solidity RUN yarn build +# Baked-in registry version +# keep for back-compat until we update all usage of the monorepo image (e.g. key-funder) ENV REGISTRY_URI="/hyperlane-registry" ARG REGISTRY_COMMIT="main" RUN git clone https://github.com/hyperlane-xyz/hyperlane-registry.git "$REGISTRY_URI" \ && cd "$REGISTRY_URI" \ && git fetch origin "$REGISTRY_COMMIT" \ && git checkout "$REGISTRY_COMMIT" + +# Add entrypoint script that allows overriding the registry commit +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh +ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000000..719396d5bd --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +# Set default registry URI, same as Dockerfile +REGISTRY_URI="/hyperlane-registry" + +# Only update registry if REGISTRY_COMMIT is set +if [ -n "$REGISTRY_COMMIT" ]; then + echo "Updating Hyperlane registry to commit: ${REGISTRY_COMMIT}" + OLDPWD=$(pwd) + cd "$REGISTRY_URI" + git fetch origin "$REGISTRY_COMMIT" + git checkout "$REGISTRY_COMMIT" + cd "$OLDPWD" +fi + +# Execute the main container command +exec "$@" diff --git a/typescript/infra/helm/warp-routes/templates/_helpers.tpl b/typescript/infra/helm/warp-routes/templates/_helpers.tpl index 2a9424b0a9..d96f267e05 100644 --- a/typescript/infra/helm/warp-routes/templates/_helpers.tpl +++ b/typescript/infra/helm/warp-routes/templates/_helpers.tpl @@ -68,12 +68,14 @@ The warp-routes container image: {{ .Values.image.repository }}:{{ .Values.image.tag }} imagePullPolicy: IfNotPresent env: - - name: LOG_FORMAT - value: json - command: + - name: LOG_FORMAT + value: json + - name: REGISTRY_COMMIT + value: {{ .Values.hyperlane.registryCommit }} + args: - ./node_modules/.bin/tsx - ./typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts - - -v + - -v - "30000" - --warpRouteId - {{ .Values.warpRouteId }} diff --git a/typescript/infra/helm/warp-routes/values.yaml b/typescript/infra/helm/warp-routes/values.yaml index a7a09d817a..69d2be36d5 100644 --- a/typescript/infra/helm/warp-routes/values.yaml +++ b/typescript/infra/helm/warp-routes/values.yaml @@ -5,6 +5,7 @@ hyperlane: runEnv: mainnet3 context: hyperlane chains: [] + registryCommit: nameOverride: '' fullnameOverride: '' externalSecrets: diff --git a/typescript/infra/scripts/warp-routes/deploy-warp-monitor.ts b/typescript/infra/scripts/warp-routes/deploy-warp-monitor.ts index 8ede7cdda5..d58af0eac6 100644 --- a/typescript/infra/scripts/warp-routes/deploy-warp-monitor.ts +++ b/typescript/infra/scripts/warp-routes/deploy-warp-monitor.ts @@ -1,7 +1,16 @@ -import { checkbox } from '@inquirer/prompts'; +import { input } from '@inquirer/prompts'; +import chalk from 'chalk'; +import { execSync } from 'child_process'; + +import { + LogFormat, + LogLevel, + configureRootLogger, + rootLogger, +} from '@hyperlane-xyz/utils'; import { Contexts } from '../../config/contexts.js'; -import { WarpRouteIds } from '../../config/environments/mainnet3/warp/warpIds.js'; +import { getRegistry } from '../../config/registry.js'; import { HelmCommand } from '../../src/utils/helm.js'; import { WarpRouteMonitorHelmManager } from '../../src/warp/helm.js'; import { @@ -13,7 +22,26 @@ import { } from '../agent-utils.js'; import { getEnvironmentConfig } from '../core-utils.js'; +async function validateRegistryCommit(commit: string) { + const registry = getRegistry(); + const registryUri = registry.getUri(); + + try { + rootLogger.info( + chalk.grey.italic(`Attempting to fetch registry commit ${commit}...`), + ); + execSync(`cd ${registryUri} && git fetch origin ${commit}`, { + stdio: 'inherit', + }); + rootLogger.info(chalk.grey.italic('Fetch completed successfully.')); + } catch (_) { + rootLogger.error(chalk.red(`Unable to fetch registry commit ${commit}.`)); + process.exit(1); + } +} + async function main() { + configureRootLogger(LogFormat.Pretty, LogLevel.Info); const { environment, warpRouteId } = await withWarpRouteId(getArgs()).argv; let warpRouteIds; @@ -23,6 +51,12 @@ async function main() { warpRouteIds = await getWarpRouteIdsInteractive(); } + const registryCommit = await input({ + message: + 'Enter the registry version to use (can be a commit, branch or tag):', + }); + await validateRegistryCommit(registryCommit); + await assertCorrectKubeContext(getEnvironmentConfig(environment)); const agentConfig = getAgentConfig(Contexts.Hyperlane, environment); @@ -31,6 +65,7 @@ async function main() { warpRouteId, environment, agentConfig.environmentChainNames, + registryCommit, ); await helmManager.runHelmCommand(HelmCommand.InstallOrUpgrade); }; @@ -42,11 +77,11 @@ async function main() { ); for (const id of warpRouteIds) { - console.log(`Deploying Warp Monitor for Warp Route ID: ${id}`); + rootLogger.info(`Deploying Warp Monitor for Warp Route ID: ${id}`); await deployWarpMonitor(id); } } main() - .then(() => console.log('Deploy successful!')) - .catch(console.error); + .then(() => rootLogger.info('Deploy successful!')) + .catch(rootLogger.error); diff --git a/typescript/infra/scripts/warp-routes/generate-warp-config.ts b/typescript/infra/scripts/warp-routes/generate-warp-config.ts index 47a39c16d8..2445ca5fc2 100644 --- a/typescript/infra/scripts/warp-routes/generate-warp-config.ts +++ b/typescript/infra/scripts/warp-routes/generate-warp-config.ts @@ -1,6 +1,7 @@ import { stringify as yamlStringify } from 'yaml'; import { WarpRouteDeployConfigSchema } from '@hyperlane-xyz/sdk'; +import { rootLogger } from '@hyperlane-xyz/utils'; import { getWarpConfig } from '../../config/warp.js'; import { writeYamlAtPath } from '../../src/utils/utils.js'; @@ -23,17 +24,17 @@ async function main() { const parsed = WarpRouteDeployConfigSchema.safeParse(warpConfig); if (!parsed.success) { - console.dir(parsed.error.format(), { depth: null }); + rootLogger.error(parsed.error.format()); return; } - console.log('Warp config:'); - console.log(yamlStringify(parsed.data, null, 2)); + rootLogger.info('Warp config:'); + rootLogger.info(yamlStringify(parsed.data, null, 2)); if (outFile) { - console.log(`Writing config to ${outFile}`); + rootLogger.info(`Writing config to ${outFile}`); writeYamlAtPath(outFile, parsed.data); } } -main().catch((err) => console.error('Error:', err)); +main().catch((err) => rootLogger.error('Error:', err)); diff --git a/typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts b/typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts index c04ed7418c..f2c971b2ed 100644 --- a/typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts +++ b/typescript/infra/scripts/warp-routes/monitor/monitor-warp-route-balances.ts @@ -9,7 +9,6 @@ import { EvmHypXERC20LockboxAdapter, IHypXERC20Adapter, MultiProtocolProvider, - RouterConfig, SealevelHypTokenAdapter, Token, TokenStandard, @@ -18,10 +17,7 @@ import { import { ProtocolType, objMap, objMerge, sleep } from '@hyperlane-xyz/utils'; import { getWarpCoreConfig } from '../../../config/registry.js'; -import { - DeployEnvironment, - getRouterConfigsForAllVms, -} from '../../../src/config/environment.js'; +import { DeployEnvironment } from '../../../src/config/environment.js'; import { fetchGCPSecret } from '../../../src/utils/gcloud.js'; import { startMetricsServer } from '../../../src/utils/metrics.js'; import { @@ -59,16 +55,12 @@ async function main() { const envConfig = getEnvironmentConfig(environment); const registry = await envConfig.getRegistry(); const chainMetadata = await registry.getMetadata(); + const chainAddresses = await registry.getAddresses(); // The Sealevel warp adapters require the Mailbox address, so we - // get router configs (that include the Mailbox address) for all chains - // and merge them with the chain metadata. - const routerConfig = await getRouterConfigsForAllVms( - envConfig, - await envConfig.getMultiProvider(), - ); - const mailboxes = objMap(routerConfig, (_chain, config: RouterConfig) => ({ - mailbox: config.mailbox, + // get mailboxes for all chains and merge them with the chain metadata. + const mailboxes = objMap(chainAddresses, (_, { mailbox }) => ({ + mailbox, })); const multiProtocolProvider = new MultiProtocolProvider( objMerge(chainMetadata, mailboxes), diff --git a/typescript/infra/scripts/warp-routes/utils.ts b/typescript/infra/scripts/warp-routes/utils.ts index 2e0fdc40b9..1c843c4fc5 100644 --- a/typescript/infra/scripts/warp-routes/utils.ts +++ b/typescript/infra/scripts/warp-routes/utils.ts @@ -19,7 +19,7 @@ export async function getRouterConfig() { ).argv; const envConfig = getEnvironmentConfig(environment); - let multiProvider = await envConfig.getMultiProvider( + const multiProvider = await envConfig.getMultiProvider( context, Role.Deployer, true, diff --git a/typescript/infra/src/agents/index.ts b/typescript/infra/src/agents/index.ts index 24fccbac07..cd1b1b206d 100644 --- a/typescript/infra/src/agents/index.ts +++ b/typescript/infra/src/agents/index.ts @@ -1,4 +1,3 @@ -import fs from 'fs'; import { join } from 'path'; import { @@ -49,11 +48,6 @@ const HELM_CHART_PATH = join( '/../../rust/main/helm/hyperlane-agent/', ); -if (!fs.existsSync(HELM_CHART_PATH + 'Chart.yaml')) - console.warn( - `Could not find helm chart at ${HELM_CHART_PATH}; the relative path may have changed.`, - ); - export abstract class AgentHelmManager extends HelmManager { abstract readonly role: AgentRole; readonly helmChartPath: string = HELM_CHART_PATH; diff --git a/typescript/infra/src/warp/helm.ts b/typescript/infra/src/warp/helm.ts index 76f55b426b..1ccfa8aa3e 100644 --- a/typescript/infra/src/warp/helm.ts +++ b/typescript/infra/src/warp/helm.ts @@ -1,7 +1,7 @@ import { confirm } from '@inquirer/prompts'; import path from 'path'; -import { difference } from '@hyperlane-xyz/utils'; +import { difference, rootLogger } from '@hyperlane-xyz/utils'; import { WarpRouteIds } from '../../config/environments/mainnet3/warp/warpIds.js'; import { DeployEnvironment } from '../../src/config/environment.js'; @@ -20,6 +20,7 @@ export class WarpRouteMonitorHelmManager extends HelmManager { readonly warpRouteId: string, readonly runEnv: DeployEnvironment, readonly environmentChainNames: string[], + readonly registryCommit: string, ) { super(); } @@ -28,13 +29,14 @@ export class WarpRouteMonitorHelmManager extends HelmManager { return { image: { repository: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', - tag: '3738b85-20250122-164718', + tag: '49992bf-20250122-142014', }, warpRouteId: this.warpRouteId, fullnameOverride: this.helmReleaseName, environment: this.runEnv, hyperlane: { chains: this.environmentChainNames, + registryCommit: this.registryCommit, }, }; } @@ -90,7 +92,7 @@ export class WarpRouteMonitorHelmManager extends HelmManager { new Set(allExpectedHelmReleaseNames), ); for (const helmRelease of unknownHelmReleases) { - console.log( + rootLogger.warn( `Unknown Warp Monitor Helm Release: ${helmRelease} (possibly a release from a stale Warp Route ID).`, ); const uninstall = await confirm({ @@ -98,10 +100,10 @@ export class WarpRouteMonitorHelmManager extends HelmManager { "Would you like to uninstall this Helm Release? Make extra sure it shouldn't exist!", }); if (uninstall) { - console.log(`Uninstalling Helm Release: ${helmRelease}`); + rootLogger.info(`Uninstalling Helm Release: ${helmRelease}`); await removeHelmRelease(helmRelease, namespace); } else { - console.log(`Skipping uninstall of Helm Release: ${helmRelease}`); + rootLogger.info(`Skipping uninstall of Helm Release: ${helmRelease}`); } } }