Minor fixes to get LL deploys running smoothly (#2125)

### Description

This PR makes some minor modifications to the deployment structure for
the Liquidity Layer. The most important thing is the embedding of the
`proxyAdmin` addresses in the LL addresses file which is not pretty, but
I did not want to put it in the SDK right now either, but could be
convinced.

In the process of running this, the LL router IGPs have been updated
which is non-material, but otherwise the deploy script runs as a no-op
now.
pull/2167/head
Nam Chu Hoai 2 years ago committed by GitHub
parent 35bcd97805
commit 482c8e77f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      typescript/infra/config/environments/testnet3/index.ts
  2. 0
      typescript/infra/config/environments/testnet3/liquidityLayer.ts
  3. 15
      typescript/infra/config/environments/testnet3/middleware/liquidity-layer/addresses.json
  4. 16
      typescript/infra/scripts/deploy.ts
  5. 19
      typescript/infra/scripts/middleware/circle-relayer.ts
  6. 6
      typescript/infra/src/config/environment.ts
  7. 2
      typescript/infra/src/middleware/liquidity-layer-relayer.ts
  8. 4
      typescript/sdk/src/deploy/HyperlaneDeployer.ts
  9. 83
      typescript/sdk/src/middleware/liquidity-layer/LiquidityLayerRouterDeployer.ts
  10. 2
      typescript/sdk/src/router/HyperlaneRouterDeployer.ts
  11. 20
      typescript/sdk/src/router/ProxiedRouterDeployer.ts

@ -13,6 +13,7 @@ import { storageGasOracleConfig } from './gas-oracle';
import { helloWorld } from './helloworld'; import { helloWorld } from './helloworld';
import { igp } from './igp'; import { igp } from './igp';
import { infrastructure } from './infrastructure'; import { infrastructure } from './infrastructure';
import { bridgeAdapterConfigs } from './liquidityLayer';
import { liquidityLayerRelayerConfig } from './middleware'; import { liquidityLayerRelayerConfig } from './middleware';
import { owners } from './owners'; import { owners } from './owners';
@ -39,6 +40,9 @@ export const environment: EnvironmentConfig = {
helloWorld, helloWorld,
owners, owners,
keyFunderConfig, keyFunderConfig,
liquidityLayerRelayerConfig, liquidityLayerConfig: {
bridgeAdapters: bridgeAdapterConfigs,
relayer: liquidityLayerRelayerConfig,
},
storageGasOracleConfig, storageGasOracleConfig,
}; };

@ -2,23 +2,28 @@
"goerli": { "goerli": {
"circleBridgeAdapter": "0xfe9d88aA85c5917822C804b949BcEDE832C02ce2", "circleBridgeAdapter": "0xfe9d88aA85c5917822C804b949BcEDE832C02ce2",
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9", "portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26" "proxyAdmin": "0x8f919348F9C4619A196Acb5e377f49E5E2C0B569",
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
}, },
"fuji": { "fuji": {
"circleBridgeAdapter": "0xfe9d88aA85c5917822C804b949BcEDE832C02ce2", "circleBridgeAdapter": "0xfe9d88aA85c5917822C804b949BcEDE832C02ce2",
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9", "portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26" "proxyAdmin": "0x13474f85b808034C911B7697dee60B7d8d50ee36",
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
}, },
"mumbai": { "mumbai": {
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9", "portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26" "proxyAdmin": "0x96b49e136581f8dfF370aDB3015D48465572a318",
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
}, },
"bsctestnet": { "bsctestnet": {
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9", "portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26" "proxyAdmin": "0xfB149BC17dD3FE858fA64D678bA0c706DEac61eE",
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
}, },
"alfajores": { "alfajores": {
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9", "portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26" "liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26",
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f"
} }
} }

@ -14,7 +14,6 @@ import {
objMap, objMap,
} from '@hyperlane-xyz/sdk'; } from '@hyperlane-xyz/sdk';
import { bridgeAdapterConfigs } from '../config/environments/test/liquidityLayer';
import { deployEnvToSdkEnv } from '../src/config/environment'; import { deployEnvToSdkEnv } from '../src/config/environment';
import { deployWithArtifacts } from '../src/deploy'; import { deployWithArtifacts } from '../src/deploy';
import { TestQuerySenderDeployer } from '../src/testcontracts/testquerysender'; import { TestQuerySenderDeployer } from '../src/testcontracts/testquerysender';
@ -73,12 +72,17 @@ async function main() {
config = await getRouterConfig(environment, multiProvider); config = await getRouterConfig(environment, multiProvider);
deployer = new InterchainQueryDeployer(multiProvider); deployer = new InterchainQueryDeployer(multiProvider);
} else if (module === Modules.LIQUIDITY_LAYER) { } else if (module === Modules.LIQUIDITY_LAYER) {
deployer = new LiquidityLayerDeployer(multiProvider);
const routerConfig = await getRouterConfig(environment, multiProvider); const routerConfig = await getRouterConfig(environment, multiProvider);
config = objMap(bridgeAdapterConfigs, (chain, conf) => ({ if (!envConfig.liquidityLayerConfig) {
...conf, throw new Error(`No liquidity layer config for ${environment}`);
...routerConfig[chain], }
})); config = objMap(
envConfig.liquidityLayerConfig.bridgeAdapters,
(chain, conf) => ({
...conf,
...routerConfig[chain],
}),
);
deployer = new LiquidityLayerDeployer(multiProvider); deployer = new LiquidityLayerDeployer(multiProvider);
} else if (module === Modules.TEST_RECIPIENT) { } else if (module === Modules.TEST_RECIPIENT) {
deployer = new TestRecipientDeployer(multiProvider); deployer = new TestRecipientDeployer(multiProvider);

@ -1,13 +1,13 @@
import path from 'path'; import path from 'path';
import { import {
Chains,
LiquidityLayerApp, LiquidityLayerApp,
attachContractsMap, attachContractsMap,
liquidityLayerFactories, liquidityLayerFactories,
objFilter,
} from '@hyperlane-xyz/sdk'; } from '@hyperlane-xyz/sdk';
import { LiquidityLayerConfig } from '@hyperlane-xyz/sdk/dist/middleware/liquidity-layer/LiquidityLayerRouterDeployer';
import { bridgeAdapterConfigs } from '../../config/environments/testnet3/token-bridge';
import { readJSON, sleep } from '../../src/utils/utils'; import { readJSON, sleep } from '../../src/utils/utils';
import { import {
getEnvironment, getEnvironment,
@ -18,6 +18,11 @@ import {
async function check() { async function check() {
const environment = await getEnvironment(); const environment = await getEnvironment();
const config = getEnvironmentConfig(environment); const config = getEnvironmentConfig(environment);
if (config.liquidityLayerConfig === undefined) {
throw new Error(`No liquidity layer config found for ${environment}`);
}
const multiProvider = await config.getMultiProvider(); const multiProvider = await config.getMultiProvider();
const dir = path.join( const dir = path.join(
__dirname, __dirname,
@ -27,14 +32,20 @@ async function check() {
); );
const addresses = readJSON(dir, 'addresses.json'); const addresses = readJSON(dir, 'addresses.json');
const contracts = attachContractsMap(addresses, liquidityLayerFactories); const contracts = attachContractsMap(addresses, liquidityLayerFactories);
const app = new LiquidityLayerApp( const app = new LiquidityLayerApp(
contracts, contracts,
multiProvider, multiProvider,
bridgeAdapterConfigs, config.liquidityLayerConfig.bridgeAdapters,
); );
while (true) { while (true) {
for (const chain of [Chains.goerli, Chains.fuji]) { for (const chain of Object.keys(
objFilter(
config.liquidityLayerConfig.bridgeAdapters,
(_, config): config is LiquidityLayerConfig => !!config.circle,
),
)) {
const txHashes = await app.fetchCircleMessageTransactions(chain); const txHashes = await app.fetchCircleMessageTransactions(chain);
const circleDispatches = ( const circleDispatches = (

@ -1,5 +1,6 @@
import { import {
AgentConnectionType, AgentConnectionType,
BridgeAdapterConfig,
ChainMap, ChainMap,
ChainMetadata, ChainMetadata,
ChainName, ChainName,
@ -44,7 +45,10 @@ export type EnvironmentConfig = {
) => Promise<MultiProvider>; ) => Promise<MultiProvider>;
helloWorld?: Partial<Record<Contexts, HelloWorldConfig>>; helloWorld?: Partial<Record<Contexts, HelloWorldConfig>>;
keyFunderConfig?: KeyFunderConfig; keyFunderConfig?: KeyFunderConfig;
liquidityLayerRelayerConfig?: LiquidityLayerRelayerConfig; liquidityLayerConfig?: {
bridgeAdapters: ChainMap<BridgeAdapterConfig>;
relayer: LiquidityLayerRelayerConfig;
};
storageGasOracleConfig?: AllStorageGasOracleConfigs; storageGasOracleConfig?: AllStorageGasOracleConfigs;
}; };

@ -59,7 +59,7 @@ function getLiquidityLayerRelayerHelmValues(
export function getLiquidityLayerRelayerConfig( export function getLiquidityLayerRelayerConfig(
coreConfig: EnvironmentConfig, coreConfig: EnvironmentConfig,
): LiquidityLayerRelayerConfig { ): LiquidityLayerRelayerConfig {
const relayerConfig = coreConfig.liquidityLayerRelayerConfig; const relayerConfig = coreConfig.liquidityLayerConfig?.relayer;
if (!relayerConfig) { if (!relayerConfig) {
throw new Error( throw new Error(
`Environment ${coreConfig.environment} does not have a LiquidityLayerRelayerConfig config`, `Environment ${coreConfig.environment} does not have a LiquidityLayerRelayerConfig config`,

@ -148,7 +148,9 @@ export abstract class HyperlaneDeployer<
connectionClient: HyperlaneConnectionClient, connectionClient: HyperlaneConnectionClient,
config: ConnectionClientConfig, config: ConnectionClientConfig,
): Promise<void> { ): Promise<void> {
this.logger(`Initializing connection client on ${local}...`); this.logger(
`Initializing connection client (if not already) on ${local}...`,
);
await this.runIfOwner(local, connectionClient, async () => { await this.runIfOwner(local, connectionClient, async () => {
// set mailbox if not already set (and configured) // set mailbox if not already set (and configured)
if (config.mailbox !== (await connectionClient.mailbox())) { if (config.mailbox !== (await connectionClient.mailbox())) {

@ -12,7 +12,7 @@ import { MultiProvider } from '../../providers/MultiProvider';
import { ProxiedRouterDeployer } from '../../router/ProxiedRouterDeployer'; import { ProxiedRouterDeployer } from '../../router/ProxiedRouterDeployer';
import { RouterConfig } from '../../router/types'; import { RouterConfig } from '../../router/types';
import { ChainMap, ChainName } from '../../types'; import { ChainMap, ChainName } from '../../types';
import { objMap } from '../../utils/objects'; import { objFilter, objMap } from '../../utils/objects';
import { LiquidityLayerFactories, liquidityLayerFactories } from './contracts'; import { LiquidityLayerFactories, liquidityLayerFactories } from './contracts';
@ -93,18 +93,32 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
this.logger(`Enroll CircleBridgeAdapters with each other`); this.logger(`Enroll CircleBridgeAdapters with each other`);
// Hack to allow use of super.enrollRemoteRouters // Hack to allow use of super.enrollRemoteRouters
await super.enrollRemoteRouters( await super.enrollRemoteRouters(
objMap(contractsMap, (_, contracts) => ({ objMap(
liquidityLayerRouter: contracts.circleBridgeAdapter, objFilter(
})) as unknown as HyperlaneContractsMap<LiquidityLayerFactories>, contractsMap,
(_, c): c is HyperlaneContracts<LiquidityLayerFactories> =>
!!c.circleBridgeAdapter,
),
(_, contracts) => ({
liquidityLayerRouter: contracts.circleBridgeAdapter,
}),
) as unknown as HyperlaneContractsMap<LiquidityLayerFactories>,
configMap, configMap,
); );
this.logger(`Enroll PortalAdapters with each other`); this.logger(`Enroll PortalAdapters with each other`);
// Hack to allow use of super.enrollRemoteRouters // Hack to allow use of super.enrollRemoteRouters
await super.enrollRemoteRouters( await super.enrollRemoteRouters(
objMap(contractsMap, (_, contracts) => ({ objMap(
liquidityLayerRouter: contracts.portalAdapter, objFilter(
})) as unknown as HyperlaneContractsMap<LiquidityLayerFactories>, contractsMap,
(_, c): c is HyperlaneContracts<LiquidityLayerFactories> =>
!!c.portalAdapter,
),
(_, contracts) => ({
liquidityLayerRouter: contracts.portalAdapter,
}),
) as unknown as HyperlaneContractsMap<LiquidityLayerFactories>,
configMap, configMap,
); );
} }
@ -115,6 +129,9 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
chain: ChainName, chain: ChainName,
config: LiquidityLayerConfig, config: LiquidityLayerConfig,
): Promise<HyperlaneContracts<LiquidityLayerFactories>> { ): Promise<HyperlaneContracts<LiquidityLayerFactories>> {
// This is just the temp owner for contracts, and HyperlaneRouterDeployer#transferOwnership actually sets the configured owner
const deployer = await this.multiProvider.getSignerAddress(chain);
const routerContracts = await super.deployContracts(chain, config); const routerContracts = await super.deployContracts(chain, config);
const bridgeAdapters: Partial< const bridgeAdapters: Partial<
@ -125,7 +142,7 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
bridgeAdapters.circleBridgeAdapter = await this.deployCircleBridgeAdapter( bridgeAdapters.circleBridgeAdapter = await this.deployCircleBridgeAdapter(
chain, chain,
config.circle, config.circle,
config.owner, deployer,
routerContracts.liquidityLayerRouter, routerContracts.liquidityLayerRouter,
); );
} }
@ -133,7 +150,7 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
bridgeAdapters.portalAdapter = await this.deployPortalAdapter( bridgeAdapters.portalAdapter = await this.deployPortalAdapter(
chain, chain,
config.portal, config.portal,
config.owner, deployer,
routerContracts.liquidityLayerRouter, routerContracts.liquidityLayerRouter,
); );
} }
@ -173,9 +190,11 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
this.logger( this.logger(
`Set wormhole domain ${wormholeDomain} for hyperlane domain ${hyperlaneDomain}`, `Set wormhole domain ${wormholeDomain} for hyperlane domain ${hyperlaneDomain}`,
); );
await this.multiProvider.handleTx( await this.runIfOwner(chain, portalAdapter, () =>
chain, this.multiProvider.handleTx(
portalAdapter.addDomain(hyperlaneDomain, wormholeDomain), chain,
portalAdapter.addDomain(hyperlaneDomain, wormholeDomain),
),
); );
} }
@ -186,11 +205,13 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
) )
) { ) {
this.logger('Set Portal as LiquidityLayerAdapter on Router'); this.logger('Set Portal as LiquidityLayerAdapter on Router');
await this.multiProvider.handleTx( await this.runIfOwner(chain, portalAdapter, () =>
chain, this.multiProvider.handleTx(
router.setLiquidityLayerAdapter( chain,
adapterConfig.type, router.setLiquidityLayerAdapter(
portalAdapter.address, adapterConfig.type,
portalAdapter.address,
),
), ),
); );
} }
@ -223,9 +244,11 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
) )
) { ) {
this.logger(`Set USDC token contract`); this.logger(`Set USDC token contract`);
await this.multiProvider.handleTx( await this.runIfOwner(chain, circleBridgeAdapter, () =>
chain, this.multiProvider.handleTx(
circleBridgeAdapter.addToken(adapterConfig.usdcAddress, 'USDC'), chain,
circleBridgeAdapter.addToken(adapterConfig.usdcAddress, 'USDC'),
),
); );
} }
// Set domain mappings // Set domain mappings
@ -242,9 +265,11 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
this.logger( this.logger(
`Set circle domain ${circleDomain} for hyperlane domain ${hyperlaneDomain}`, `Set circle domain ${circleDomain} for hyperlane domain ${hyperlaneDomain}`,
); );
await this.multiProvider.handleTx( await this.runIfOwner(chain, circleBridgeAdapter, () =>
chain, this.multiProvider.handleTx(
circleBridgeAdapter.addDomain(hyperlaneDomain, circleDomain), chain,
circleBridgeAdapter.addDomain(hyperlaneDomain, circleDomain),
),
); );
} }
@ -255,11 +280,13 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
) )
) { ) {
this.logger('Set Circle as LiquidityLayerAdapter on Router'); this.logger('Set Circle as LiquidityLayerAdapter on Router');
await this.multiProvider.handleTx( await this.runIfOwner(chain, circleBridgeAdapter, () =>
chain, this.multiProvider.handleTx(
router.setLiquidityLayerAdapter( chain,
adapterConfig.type, router.setLiquidityLayerAdapter(
circleBridgeAdapter.address, adapterConfig.type,
circleBridgeAdapter.address,
),
), ),
); );
} }

@ -115,7 +115,7 @@ export abstract class HyperlaneRouterDeployer<
// skip if no enrollments are needed // skip if no enrollments are needed
if (domains.length === 0) { if (domains.length === 0) {
return; continue;
} }
await super.runIfOwner(chain, this.router(contracts), async () => { await super.runIfOwner(chain, this.router(contracts), async () => {

@ -1,4 +1,5 @@
import { Router } from '@hyperlane-xyz/core'; import { Router } from '@hyperlane-xyz/core';
import { eqAddress } from '@hyperlane-xyz/utils/dist/src/utils';
import { HyperlaneContracts } from '../contracts'; import { HyperlaneContracts } from '../contracts';
import { ChainName } from '../types'; import { ChainName } from '../types';
@ -50,13 +51,18 @@ export abstract class ProxiedRouterDeployer<
await this.initializeArgs(chain, config), await this.initializeArgs(chain, config),
); );
this.logger(`Transferring ownership of proxy admin to ${config.owner}`); await super.runIfOwner(chain, proxyAdmin, async () => {
await super.runIfOwner(chain, proxyAdmin, () => this.logger(`Checking ownership of proxy admin to ${config.owner}`);
this.multiProvider.handleTx(
chain, if (!eqAddress(await proxyAdmin.owner(), config.owner)) {
proxyAdmin.transferOwnership(config.owner), this.logger(`Transferring ownership of proxy admin to ${config.owner}`);
), return this.multiProvider.handleTx(
); chain,
proxyAdmin.transferOwnership(config.owner),
);
}
return;
});
return { return {
[this.routerContractName]: proxiedRouter, [this.routerContractName]: proxiedRouter,

Loading…
Cancel
Save