feat(infra): deploy to a set of specific chains (#4040)

- feat(infra): deploy to a set of specific chains
- allows users to specify more than 1 target chain to deploy to
- provides suggestions of available chains to deploy (given local
registry)


![image](https://github.com/hyperlane-xyz/hyperlane-monorepo/assets/10051819/020939a9-220d-47dc-b434-e9342ea2ff0f)

---------

Signed-off-by: Paul Balaji <10051819+paulbalaji@users.noreply.github.com>
pull/4042/head
Paul Balaji 4 months ago committed by GitHub
parent 1876f68127
commit 7adbd27634
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      typescript/infra/scripts/agent-utils.ts
  2. 10
      typescript/infra/scripts/agents/utils.ts
  3. 25
      typescript/infra/scripts/deploy.ts
  4. 37
      typescript/infra/src/deployment/deploy.ts

@ -116,6 +116,18 @@ export function withChain<T>(args: Argv<T>) {
.alias('c', 'chain');
}
export function withChains<T>(args: Argv<T>) {
return (
args
.describe('chains', 'Set of chains to perform actions on.')
.array('chains')
.choices('chains', getChains())
// Ensure chains are unique
.coerce('chains', (chains: string[]) => Array.from(new Set(chains)))
.alias('c', 'chains')
);
}
export function withProtocol<T>(args: Argv<T>) {
return args
.describe('protocol', 'protocol type')

@ -12,6 +12,7 @@ import {
assertCorrectKubeContext,
getArgs,
withAgentRole,
withChains,
withContext,
} from '../agent-utils.js';
import { getConfigsBasedOnArgs } from '../core-utils.js';
@ -69,14 +70,9 @@ export class AgentCli {
protected async init() {
if (this.initialized) return;
const argv = await withAgentRole(withContext(getArgs()))
const argv = await withChains(withAgentRole(withContext(getArgs())))
.describe('dry-run', 'Run through the steps without making any changes')
.boolean('dry-run')
.describe('chains', 'Specific chains to perform validator actions on.')
.array('chains')
// Ensure chains are unique
.coerce('chains', (chains: string[]) => Array.from(new Set(chains)))
.alias('c', 'chains').argv;
.boolean('dry-run').argv;
if (
argv.chains &&

@ -22,7 +22,7 @@ import {
LiquidityLayerDeployer,
TestRecipientDeployer,
} from '@hyperlane-xyz/sdk';
import { objMap } from '@hyperlane-xyz/utils';
import { objFilter, objMap } from '@hyperlane-xyz/utils';
import { Contexts } from '../config/contexts.js';
import { core as coreConfig } from '../config/environments/mainnet3/core.js';
@ -44,7 +44,7 @@ import {
getArgs,
getModuleDirectory,
withBuildArtifactPath,
withChain,
withChains,
withConcurrentDeploy,
withContext,
withModuleAndFork,
@ -57,12 +57,12 @@ async function main() {
module,
fork,
environment,
chain,
buildArtifactPath,
chains,
concurrentDeploy,
} = await withContext(
withConcurrentDeploy(
withChain(withModuleAndFork(withBuildArtifactPath(getArgs()))),
withChains(withModuleAndFork(withBuildArtifactPath(getArgs()))),
),
).argv;
const envConfig = getEnvironmentConfig(environment);
@ -231,7 +231,12 @@ async function main() {
// prompt for confirmation in production environments
if (environment !== 'test' && !fork) {
const confirmConfig = chain ? config[chain] : config;
const confirmConfig =
chains && chains.length > 0
? objFilter(config, (chain, _): _ is unknown =>
(chains ?? []).includes(chain),
)
: config;
console.log(JSON.stringify(confirmConfig, null, 2));
const { value: confirmed } = await prompts({
type: 'confirm',
@ -244,13 +249,15 @@ async function main() {
}
}
await deployWithArtifacts(
config,
await deployWithArtifacts({
configMap: config as ChainMap<unknown>, // TODO: fix this typing
deployer,
cache,
chain ?? fork,
// Use chains if provided, otherwise deploy to all chains
// If fork is provided, deploy to fork only
targetNetworks: chains ?? !fork ? [] : [fork],
agentConfig,
);
});
}
main()

@ -11,6 +11,7 @@ import {
} from '@hyperlane-xyz/sdk';
import {
ProtocolType,
objFilter,
objMap,
objMerge,
promiseObjAll,
@ -35,22 +36,28 @@ import {
writeMergedJSONAtPath,
} from '../utils/utils.js';
export async function deployWithArtifacts<Config extends object>(
configMap: ChainMap<Config>,
deployer: HyperlaneDeployer<Config, any>,
export async function deployWithArtifacts<Config extends object>({
configMap,
deployer,
cache,
targetNetworks,
agentConfig,
}: {
configMap: ChainMap<Config>;
deployer: HyperlaneDeployer<Config, any>;
cache: {
verification: string;
read: boolean;
write: boolean;
environment: DeployEnvironment;
module: Modules;
},
targetNetwork?: ChainName,
};
targetNetworks: ChainName[];
agentConfig?: {
multiProvider: MultiProvider;
environment: DeployEnvironment;
},
) {
};
}) {
if (cache.read) {
const addressesMap = getAddresses(cache.environment, cache.module);
deployer.cacheAddressesMap(addressesMap);
@ -64,13 +71,17 @@ export async function deployWithArtifacts<Config extends object>(
process.exit(0); // Exit the process
});
// Filter the config map to only deploy the target networks
let targetConfigMap = configMap;
if (targetNetworks.length > 0) {
targetConfigMap = objFilter(configMap, (chain, _): _ is Config =>
targetNetworks.includes(chain),
);
}
// Deploy the contracts
try {
if (targetNetwork) {
deployer.deployedContracts[targetNetwork] =
await deployer.deployContracts(targetNetwork, configMap[targetNetwork]);
} else {
await deployer.deploy(configMap);
}
await deployer.deploy(targetConfigMap);
} catch (e) {
console.error('Failed to deploy contracts', e);
}

Loading…
Cancel
Save