From 9fd8f8d66de239554603b60f6719d544f1b634cc Mon Sep 17 00:00:00 2001 From: -f Date: Thu, 21 Sep 2023 14:17:41 -0400 Subject: [PATCH 01/18] hyperlane interceptor --- .../sdk/src/hook/HyperlaneHookDeployer.ts | 104 ------------------ .../src/hook/HyperlaneInterceptorDeployer.ts | 85 ++++++++++++++ typescript/sdk/src/hook/MerkleHookDeployer.ts | 42 +++++++ typescript/sdk/src/hook/config.ts | 16 +-- typescript/sdk/src/hook/contracts.ts | 29 +++-- typescript/sdk/src/hook/types.ts | 13 ++- typescript/sdk/src/index.ts | 10 +- 7 files changed, 167 insertions(+), 132 deletions(-) delete mode 100644 typescript/sdk/src/hook/HyperlaneHookDeployer.ts create mode 100644 typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts create mode 100644 typescript/sdk/src/hook/MerkleHookDeployer.ts diff --git a/typescript/sdk/src/hook/HyperlaneHookDeployer.ts b/typescript/sdk/src/hook/HyperlaneHookDeployer.ts deleted file mode 100644 index c5119d4fb9..0000000000 --- a/typescript/sdk/src/hook/HyperlaneHookDeployer.ts +++ /dev/null @@ -1,104 +0,0 @@ -import debug from 'debug'; - -import { objFilter, objMap, promiseObjAll } from '@hyperlane-xyz/utils'; - -import { - HyperlaneAddressesMap, - HyperlaneContracts, - HyperlaneContractsMap, -} from '../contracts/types'; -import { CoreFactories } from '../core/contracts'; -import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; -import { MultiProvider } from '../providers/MultiProvider'; -import { ChainMap, ChainName } from '../types'; - -import { isHookConfig, isISMConfig } from './config'; -import { OptimismHookFactories, optimismHookFactories } from './contracts'; -import { HookConfig, MessageHookConfig, NoMetadataIsmConfig } from './types'; - -// TODO: make generic from optimism hooks -export class HyperlaneHookDeployer extends HyperlaneDeployer< - HookConfig, - OptimismHookFactories -> { - constructor( - multiProvider: MultiProvider, - public core: HyperlaneAddressesMap, - ) { - super(multiProvider, optimismHookFactories, { - logger: debug('hyperlane:HookDeployer'), - }); - } - - async deploy( - configMap: ChainMap, - ): Promise> { - // deploy ISMs first - const ismConfigMap = objFilter( - configMap, - (_, config): config is NoMetadataIsmConfig => isISMConfig(config), - ); - await super.deploy(ismConfigMap); - - // deploy Hooks next - const hookConfigMap = objFilter( - configMap, - (_, config): config is MessageHookConfig => isHookConfig(config), - ); - await super.deploy(hookConfigMap); - - // configure ISMs with authorized hooks - await promiseObjAll( - objMap(hookConfigMap, (hookChain, hookConfig) => { - const hookAddress = this.deployedContracts[hookChain].hook.address; - const ism = this.deployedContracts[hookConfig.destination].ism; - return this.multiProvider.handleTx( - hookConfig.destination, - ism.setAuthorizedHook(hookAddress), - ); - }), - ); - - return this.deployedContracts; - } - - async deployContracts( - chain: ChainName, - config: HookConfig, - ): Promise> { - this.logger(`Deploying ${config.hookContractType} on ${chain}`); - if (isISMConfig(config)) { - const ism = await this.multiProvider.handleDeploy( - chain, - this.factories.ism, - [config.nativeBridge], - ); - // @ts-ignore - return { ism, hook: undefined }; - } else if (isHookConfig(config)) { - const remoteIsm = this.deployedContracts[config.destination].ism; - if (!remoteIsm) { - throw new Error(`Remote ISM not found for ${config.destination}`); - } - - const mailbox = this.core[chain].mailbox; - if (!mailbox) { - throw new Error(`Mailbox not found for ${chain}`); - } - const destinationDomain = this.multiProvider.getDomainId( - config.destination, - ); - - const hook = await this.multiProvider.handleDeploy( - chain, - this.factories.hook, - [mailbox, destinationDomain, remoteIsm.address, config.nativeBridge], - ); - - // @ts-ignore - return { hook, ism: undefined }; - } else { - throw new Error(`Invalid config type: ${config}`); - } - } -} diff --git a/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts b/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts new file mode 100644 index 0000000000..7eabba3496 --- /dev/null +++ b/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts @@ -0,0 +1,85 @@ +import { objFilter } from '@hyperlane-xyz/utils'; + +import { + HyperlaneContracts, + HyperlaneContractsMap, + HyperlaneFactories, +} from '../contracts/types'; +import { + DeployerOptions, + HyperlaneDeployer, +} from '../deploy/HyperlaneDeployer'; +import { MultiProvider } from '../providers/MultiProvider'; +import { ChainMap, ChainName } from '../types'; + +import { isHookConfig } from './config'; +import { PostDispatchHookConfig } from './types'; + +export abstract class HyperlaneInterceptorDeployer< + HookConfig extends PostDispatchHookConfig, + HookFactories extends HyperlaneFactories, +> extends HyperlaneDeployer { + constructor( + multiProvider: MultiProvider, + factories: HookFactories, + options?: DeployerOptions, + ) { + super(multiProvider, factories, options); + } + + async deploy( + configMap: ChainMap, + ): Promise> { + // TODO: uncomment when ISMs are implemented + // const ismConfigMap = objFilter( + // configMap, + // (_, config: IsmConfig): config is IsmConfig => !isHookConfig(config), + // ); + // await super.deploy(ismConfigMap); + + // deploy Hooks next + const hookConfigMap = objFilter( + configMap, + (_, config: HookConfig): config is HookConfig => isHookConfig(config), + ); + await super.deploy(hookConfigMap); + + // TODO: post deploy steps + // configure ISMs with authorized hooks + // await promiseObjAll( + // objMap(hookConfigMap, (hookChain, hookConfig) => { + // const hookAddress = this.deployedContracts[hookChain].hook.address; + // const ism = this.deployedContracts[hookConfig.destination].ism; + // return this.multiProvider.handleTx( + // hookConfig.destination, + // ism.setAuthorizedHook(hookAddress), + // ); + // }), + // ); + + return this.deployedContracts; + } + + async deployContracts( + chain: ChainName, + config: HookConfig, + ): Promise> { + this.logger(`Deploying ${config.hookContractType} on ${chain}`); + if (isHookConfig(config)) { + return this.deployHookContracts(chain, config); + } else { + throw new Error('ISM as object unimplemented'); + } + } + + protected abstract deployHookContracts( + chain: ChainName, + config: HookConfig, + ): Promise>; + + // protected abstract deployIsmContracts( + // chain: ChainName, + // config: IsmConfig, + // ): Promise>; + // } +} diff --git a/typescript/sdk/src/hook/MerkleHookDeployer.ts b/typescript/sdk/src/hook/MerkleHookDeployer.ts new file mode 100644 index 0000000000..d2a10d56c8 --- /dev/null +++ b/typescript/sdk/src/hook/MerkleHookDeployer.ts @@ -0,0 +1,42 @@ +import debug from 'debug'; + +import { MerkleTreeHook__factory } from '@hyperlane-xyz/core'; + +import { HyperlaneContracts } from '../contracts/types'; +import { MultiProvider } from '../providers/MultiProvider'; +import { ChainName } from '../types'; + +import { HyperlaneInterceptorDeployer } from './HyperlaneInterceptorDeployer'; +import { MerkleRootHookFactories } from './contracts'; +import { MerkleTreeHookConfig } from './types'; + +export class MerkleTreeInterceptorDeployer extends HyperlaneInterceptorDeployer< + MerkleTreeHookConfig, + MerkleRootHookFactories +> { + constructor( + multiProvider: MultiProvider, + factories: MerkleRootHookFactories, + ) { + super(multiProvider, factories, { + logger: debug('hyperlane:MerkleTreeInterceptorDeployer'), + }); + } + + async deployHookContracts( + chain: ChainName, + config: MerkleTreeHookConfig, + ): Promise> { + this.logger(`Deploying Merkle Tree Hook to ${chain}`); + const merkleTreeFactory = new MerkleTreeHook__factory(); + const merkleTreeHook = await this.multiProvider.handleDeploy( + chain, + merkleTreeFactory, + [config.mailbox], + ); + + return { + hook: merkleTreeHook, + }; + } +} diff --git a/typescript/sdk/src/hook/config.ts b/typescript/sdk/src/hook/config.ts index d013678ab3..056373003f 100644 --- a/typescript/sdk/src/hook/config.ts +++ b/typescript/sdk/src/hook/config.ts @@ -1,14 +1,6 @@ -import { - HookConfig, - HookContractType, - MessageHookConfig, - NoMetadataIsmConfig, -} from './types'; +import { HookContractType, PostDispatchHookConfig } from './types'; -export const isISMConfig = ( - config: HookConfig, -): config is NoMetadataIsmConfig => - config.hookContractType === HookContractType.ISM; - -export const isHookConfig = (config: HookConfig): config is MessageHookConfig => +export const isHookConfig = ( + config: PostDispatchHookConfig, +): config is PostDispatchHookConfig => config.hookContractType === HookContractType.HOOK; diff --git a/typescript/sdk/src/hook/contracts.ts b/typescript/sdk/src/hook/contracts.ts index ba9599e9a4..e37ad796b5 100644 --- a/typescript/sdk/src/hook/contracts.ts +++ b/typescript/sdk/src/hook/contracts.ts @@ -1,18 +1,29 @@ import { - AbstractMessageIdAuthHook__factory, - AbstractMessageIdAuthorizedIsm__factory, + MerkleTreeHook__factory, OPStackHook__factory, - OPStackIsm__factory, + OverheadIgp__factory, + StorageGasOracle__factory, } from '@hyperlane-xyz/core'; -export type HookFactories = { - hook: AbstractMessageIdAuthHook__factory; - ism: AbstractMessageIdAuthorizedIsm__factory; +import { proxiedFactories } from '../router/types'; + +export const merkleRootHookFactories = { + hook: new MerkleTreeHook__factory(), +}; +export type MerkleRootHookFactories = typeof merkleRootHookFactories; + +export const igpFactories = { + // interchainGasPaymaster: new InterchainGasPaymaster__factory(), + interchainGasPaymaster: new OverheadIgp__factory(), + storageGasOracle: new StorageGasOracle__factory(), + ...proxiedFactories, }; -export const optimismHookFactories = { +export const opStackHookFactories = { hook: new OPStackHook__factory(), - ism: new OPStackIsm__factory(), }; -export type OptimismHookFactories = typeof optimismHookFactories; +export type PostDispatchHookFactories = + | typeof opStackHookFactories + | typeof merkleRootHookFactories + | typeof igpFactories; diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index e69e3cb72c..054e05936f 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -1,5 +1,6 @@ import type { Address } from '@hyperlane-xyz/utils'; +import type { IsmConfig } from '../ism/types'; import { ChainName } from '../types'; export enum HookContractType { @@ -7,16 +8,24 @@ export enum HookContractType { ISM = 'ism', } -export type MessageHookConfig = { +export type OpStackHookConfig = { hookContractType: HookContractType.HOOK; + mailbox: Address; nativeBridge: Address; remoteIsm?: Address; destination: ChainName; }; +export type MerkleTreeHookConfig = { + hookContractType: HookContractType.HOOK; + mailbox: Address; +}; + +export type PostDispatchHookConfig = OpStackHookConfig | MerkleTreeHookConfig; + export type NoMetadataIsmConfig = { hookContractType: HookContractType.ISM; nativeBridge: Address; }; -export type HookConfig = MessageHookConfig | NoMetadataIsmConfig; +export type InterceptorConfig = PostDispatchHookConfig | IsmConfig; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 2012bb8052..5dd46c9376 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -60,7 +60,7 @@ export { TestCoreDeployer } from './core/TestCoreDeployer'; export { EvmCoreAdapter } from './core/adapters/EvmCoreAdapter'; export { SealevelCoreAdapter } from './core/adapters/SealevelCoreAdapter'; export { ICoreAdapter } from './core/adapters/types'; -export { CoreFactories, coreFactories, CoreAddresses } from './core/contracts'; +export { CoreAddresses, CoreFactories, coreFactories } from './core/contracts'; export { HyperlaneLifecyleEvent } from './core/events'; export { CoreConfig, @@ -108,12 +108,12 @@ export { IgpViolationType, OverheadIgpConfig, } from './gas/types'; -export { HyperlaneHookDeployer } from './hook/HyperlaneHookDeployer'; +export { HyperlaneInterceptorDeployer } from './hook/HyperlaneInterceptorDeployer'; export { - HookConfig, HookContractType, - MessageHookConfig, + InterceptorConfig, NoMetadataIsmConfig, + PostDispatchHookConfig, } from './hook/types'; export { HyperlaneIsmFactory, @@ -125,8 +125,8 @@ export { DeployedIsm, IsmConfig, ModuleType, - MultisigIsmConfig, MultisigConfig, + MultisigIsmConfig, RoutingIsmConfig, } from './ism/types'; export { From 67adfd2746b2641a49e5d12a59d24de2f38dd308 Mon Sep 17 00:00:00 2001 From: -f Date: Tue, 26 Sep 2023 15:56:43 -0400 Subject: [PATCH 02/18] merkle interceptor --- .../config/environments/mainnet2/hooks.ts | 65 ++++++++++--------- .../config/environments/mainnet2/index.ts | 4 +- .../infra/config/environments/test/hooks.ts | 64 +++++++++--------- .../infra/config/environments/test/index.ts | 6 +- .../config/environments/testnet3/hooks.ts | 62 +++++++++--------- .../config/environments/testnet3/index.ts | 4 +- typescript/infra/scripts/deploy.ts | 40 +++++++++++- typescript/infra/src/config/environment.ts | 4 +- .../src/hook/HyperlaneInterceptorDeployer.ts | 47 +++++++------- typescript/sdk/src/hook/MerkleHookDeployer.ts | 42 ------------ .../src/hook/MerkleRootInterceptorDeployer.ts | 65 +++++++++++++++++++ typescript/sdk/src/hook/config.ts | 11 +++- typescript/sdk/src/hook/contracts.ts | 13 ++-- typescript/sdk/src/hook/types.ts | 16 +++-- typescript/sdk/src/index.ts | 3 + typescript/sdk/src/ism/HyperlaneIsmFactory.ts | 20 ++++++ 16 files changed, 282 insertions(+), 184 deletions(-) delete mode 100644 typescript/sdk/src/hook/MerkleHookDeployer.ts create mode 100644 typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts diff --git a/typescript/infra/config/environments/mainnet2/hooks.ts b/typescript/infra/config/environments/mainnet2/hooks.ts index 52d02b2cb7..8827d5121b 100644 --- a/typescript/infra/config/environments/mainnet2/hooks.ts +++ b/typescript/infra/config/environments/mainnet2/hooks.ts @@ -1,35 +1,36 @@ -import { - ChainMap, - HookConfig, - HookContractType, - MessageHookConfig, - NoMetadataIsmConfig, - filterByChains, -} from '@hyperlane-xyz/sdk'; -import { objMap } from '@hyperlane-xyz/utils'; +// import { +// ChainMap, +// HookContractType, +// InterceptorConfig, +// NoMetadataIsmConfig, +// OpStackHookConfig, +// filterByChains, +// } from '@hyperlane-xyz/sdk'; +// import { objMap } from '@hyperlane-xyz/utils'; -import { owners } from './owners'; +// import { owners } from './owners'; -const chainNameFilter = new Set(['ethereum', 'optimism']); -const filteredOwnersResult = filterByChains(owners, chainNameFilter); +// const chainNameFilter = new Set(['ethereum', 'optimism']); +// const filteredOwnersResult = filterByChains(owners, chainNameFilter); -export const hooks: ChainMap = objMap( - filteredOwnersResult, - (chain) => { - if (chain === 'ethereum') { - const hookConfig: MessageHookConfig = { - hookContractType: HookContractType.HOOK, - nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1', - remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first - destination: 'optimism', - }; - return hookConfig; - } else { - const ismConfig: NoMetadataIsmConfig = { - hookContractType: HookContractType.ISM, - nativeBridge: '0x4200000000000000000000000000000000000007', - }; - return ismConfig; - } - }, -); +// export const hooks: ChainMap = objMap( +// filteredOwnersResult, +// (chain) => { +// if (chain === 'ethereum') { +// const hookConfig: OpStackHookConfig = { +// hookContractType: HookContractType.HOOK, +// mailbox: '0x23', +// nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1', +// remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first +// destination: 'optimism', +// }; +// return hookConfig; +// } else { +// const ismConfig: NoMetadataIsmConfig = { +// hookContractType: HookContractType.ISM, +// nativeBridge: '0x4200000000000000000000000000000000000007', +// }; +// return ismConfig; +// } +// }, +// ); diff --git a/typescript/infra/config/environments/mainnet2/index.ts b/typescript/infra/config/environments/mainnet2/index.ts index 7af8b320a0..17b2839309 100644 --- a/typescript/infra/config/environments/mainnet2/index.ts +++ b/typescript/infra/config/environments/mainnet2/index.ts @@ -14,7 +14,7 @@ import { core } from './core'; import { keyFunderConfig } from './funding'; import { storageGasOracleConfig } from './gas-oracle'; import { helloWorld } from './helloworld'; -import { hooks } from './hooks'; +// import { hooks } from './hooks'; import { igp } from './igp'; import { infrastructure } from './infrastructure'; import { bridgeAdapterConfigs, relayerConfig } from './liquidityLayer'; @@ -45,7 +45,7 @@ export const environment: EnvironmentConfig = { igp, owners, infra: infrastructure, - hooks, + // hooks, helloWorld, keyFunderConfig, storageGasOracleConfig, diff --git a/typescript/infra/config/environments/test/hooks.ts b/typescript/infra/config/environments/test/hooks.ts index cf0e4a9db9..e86bed2911 100644 --- a/typescript/infra/config/environments/test/hooks.ts +++ b/typescript/infra/config/environments/test/hooks.ts @@ -1,35 +1,35 @@ -import { - ChainMap, - HookConfig, - HookContractType, - MessageHookConfig, - NoMetadataIsmConfig, - filterByChains, -} from '@hyperlane-xyz/sdk'; -import { objMap } from '@hyperlane-xyz/utils'; +// import { +// ChainMap, +// HookContractType, +// InterceptorConfig, +// NoMetadataIsmConfig, +// OpStackHookConfig, +// filterByChains, +// } from '@hyperlane-xyz/sdk'; +// import { objMap } from '@hyperlane-xyz/utils'; -import { owners } from './owners'; +// import { owners } from './owners'; -const chainNameFilter = new Set(['test1', 'test2']); -const filteredOwnersResult = filterByChains(owners, chainNameFilter); +// const chainNameFilter = new Set(['test1', 'test2']); +// const filteredOwnersResult = filterByChains(owners, chainNameFilter); -export const hooks: ChainMap = objMap( - filteredOwnersResult, - (chain) => { - if (chain === 'test1') { - const hookConfig: MessageHookConfig = { - hookContractType: HookContractType.HOOK, - nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1', - remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first - destination: 'test2', - }; - return hookConfig; - } else { - const ismConfig: NoMetadataIsmConfig = { - hookContractType: HookContractType.ISM, - nativeBridge: '0x4200000000000000000000000000000000000007', - }; - return ismConfig; - } - }, -); +// export const hooks: ChainMap = objMap( +// filteredOwnersResult, +// (chain) => { +// if (chain === 'test1') { +// const hookConfig: OpStackHookConfig = { +// hookContractType: HookContractType.HOOK, +// nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1', +// remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first +// destination: 'test2', +// }; +// return hookConfig; +// } else { +// const ismConfig: NoMetadataIsmConfig = { +// hookContractType: HookContractType.ISM, +// nativeBridge: '0x4200000000000000000000000000000000000007', +// }; +// return ismConfig; +// } +// }, +// ); diff --git a/typescript/infra/config/environments/test/index.ts b/typescript/infra/config/environments/test/index.ts index 8cb378e574..d0a3c7dac3 100644 --- a/typescript/infra/config/environments/test/index.ts +++ b/typescript/infra/config/environments/test/index.ts @@ -1,6 +1,6 @@ import { JsonRpcProvider } from '@ethersproject/providers'; -import { MultiProvider, TestChains } from '@hyperlane-xyz/sdk'; +import { MultiProvider } from '@hyperlane-xyz/sdk'; import { EnvironmentConfig } from '../../../src/config'; @@ -8,7 +8,7 @@ import { agents } from './agent'; import { testConfigs } from './chains'; import { core } from './core'; import { storageGasOracleConfig } from './gas-oracle'; -import { hooks } from './hooks'; +// import { hooks } from './hooks'; import { igp } from './igp'; import { infra } from './infra'; import { owners } from './owners'; @@ -18,7 +18,7 @@ export const environment: EnvironmentConfig = { chainMetadataConfigs: testConfigs, agents, core, - hooks, + // hooks, igp, owners, infra, diff --git a/typescript/infra/config/environments/testnet3/hooks.ts b/typescript/infra/config/environments/testnet3/hooks.ts index 2e3505f26f..2f616c68b6 100644 --- a/typescript/infra/config/environments/testnet3/hooks.ts +++ b/typescript/infra/config/environments/testnet3/hooks.ts @@ -1,34 +1,34 @@ -import { - ChainMap, - HookConfig, - HookContractType, - MessageHookConfig, - NoMetadataIsmConfig, - filterByChains, -} from '@hyperlane-xyz/sdk'; -import { objMap } from '@hyperlane-xyz/utils'; +// import { +// ChainMap, +// HookContractType, +// InterceptorConfig, +// NoMetadataIsmConfig, +// OpStackHookConfig, +// filterByChains, +// } from '@hyperlane-xyz/sdk'; +// import { objMap } from '@hyperlane-xyz/utils'; -import { owners } from './owners'; +// import { owners } from './owners'; -const chainNameFilter = new Set(['goerli', 'optimismgoerli']); -const filteredOwnersResult = filterByChains(owners, chainNameFilter); +// const chainNameFilter = new Set(['goerli', 'optimismgoerli']); +// const filteredOwnersResult = filterByChains(owners, chainNameFilter); -export const hooks: ChainMap = objMap( - filteredOwnersResult, - (chain) => { - if (chain === 'goerli') { - const hookConfig: MessageHookConfig = { - hookContractType: HookContractType.HOOK, - nativeBridge: '0x5086d1eEF304eb5284A0f6720f79403b4e9bE294', - destination: 'optimismgoerli', - }; - return hookConfig; - } else { - const ismConfig: NoMetadataIsmConfig = { - hookContractType: HookContractType.ISM, - nativeBridge: '0x4200000000000000000000000000000000000007', - }; - return ismConfig; - } - }, -); +// export const hooks: ChainMap = objMap( +// filteredOwnersResult, +// (chain) => { +// if (chain === 'goerli') { +// const hookConfig: OpStackHookConfig = { +// hookContractType: HookContractType.HOOK, +// nativeBridge: '0x5086d1eEF304eb5284A0f6720f79403b4e9bE294', +// destination: 'optimismgoerli', +// }; +// return hookConfig; +// } else { +// const ismConfig: NoMetadataIsmConfig = { +// hookContractType: HookContractType.ISM, +// nativeBridge: '0x4200000000000000000000000000000000000007', +// }; +// return ismConfig; +// } +// }, +// ); diff --git a/typescript/infra/config/environments/testnet3/index.ts b/typescript/infra/config/environments/testnet3/index.ts index 27cd017bc4..9bb2134b6c 100644 --- a/typescript/infra/config/environments/testnet3/index.ts +++ b/typescript/infra/config/environments/testnet3/index.ts @@ -14,7 +14,7 @@ import { core } from './core'; import { keyFunderConfig } from './funding'; import { storageGasOracleConfig } from './gas-oracle'; import { helloWorld } from './helloworld'; -import { hooks } from './hooks'; +// import { hooks } from './hooks'; import { igp } from './igp'; import { infrastructure } from './infrastructure'; import { bridgeAdapterConfigs } from './liquidityLayer'; @@ -46,7 +46,7 @@ export const environment: EnvironmentConfig = { igp, infra: infrastructure, helloWorld, - hooks, + // hooks, owners, keyFunderConfig, liquidityLayerConfig: { diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index 7ce9d3a7c4..026944dab3 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -1,4 +1,3 @@ -import { getAddress } from 'ethers/lib/utils'; import path from 'path'; import { HelloWorldDeployer } from '@hyperlane-xyz/helloworld'; @@ -10,10 +9,15 @@ import { HyperlaneIgpDeployer, HyperlaneIsmFactory, HyperlaneIsmFactoryDeployer, + InterceptorConfig, InterchainAccountDeployer, InterchainQueryDeployer, LiquidityLayerDeployer, + MerkleRootInterceptorDeployer, + ModuleType, + defaultMultisigIsmConfigs, } from '@hyperlane-xyz/sdk'; +import { HookContractType } from '@hyperlane-xyz/sdk/src'; import { objMap } from '@hyperlane-xyz/utils'; import { Contexts } from '../config/contexts'; @@ -22,7 +26,6 @@ import { deployWithArtifacts } from '../src/deployment/deploy'; import { TestQuerySenderDeployer } from '../src/deployment/testcontracts/testquerysender'; import { TestRecipientDeployer } from '../src/deployment/testcontracts/testrecipient'; import { impersonateAccount, useLocalProvider } from '../src/utils/fork'; -import { readJSON } from '../src/utils/utils'; import { Modules, @@ -67,6 +70,7 @@ async function main() { config = objMap(envConfig.core, (_chain) => true); deployer = new HyperlaneIsmFactoryDeployer(multiProvider); } else if (module === Modules.CORE) { + console.log(envConfig); config = envConfig.core; const ismFactory = HyperlaneIsmFactory.fromAddressesMap( getAddresses(environment, Modules.ISM_FACTORY), @@ -74,9 +78,39 @@ async function main() { ); deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory); } else if (module === Modules.HOOK) { - throw new Error('Hook deployment unimplemented'); + // throw new Error('Hook deployment unimplemented'); // config = envConfig.hooks; // deployer = new HyperlaneHookDeployer(multiProvider); + // if (envConfig.hooks) { + // config = envConfig.hooks; + // console.log('envConfig: ', config); + // deployer = new MerkleTreeInterceptorDeployer(multiProvider); + // } else { + + const mrConfig: ChainMap = { + test1: { + type: HookContractType.HOOK, + mailbox: '0xb7f8bc63bbcad18155201308c8f3540b07f84f5e', + }, + test2: { + type: ModuleType.MERKLE_ROOT_MULTISIG, + validators: defaultMultisigIsmConfigs.optimism.validators, + threshold: defaultMultisigIsmConfigs.optimism.threshold, + }, + }; + + config = mrConfig; + const ismFactory = HyperlaneIsmFactory.fromAddressesMap( + getAddresses(environment, Modules.ISM_FACTORY), + multiProvider, + ); + deployer = new MerkleRootInterceptorDeployer( + multiProvider, + ismFactory, + '0xb7f8bc63bbcad18155201308c8f3540b07f84f5e', + ); + // throw new Error('Hook deployment unimplemented'); + // } } else if (module === Modules.INTERCHAIN_GAS_PAYMASTER) { config = envConfig.igp; deployer = new HyperlaneIgpDeployer(multiProvider); diff --git a/typescript/infra/src/config/environment.ts b/typescript/infra/src/config/environment.ts index 0d8cf88e1c..f3e8f401be 100644 --- a/typescript/infra/src/config/environment.ts +++ b/typescript/infra/src/config/environment.ts @@ -5,8 +5,8 @@ import { ChainMetadata, ChainName, CoreConfig, - HookConfig, HyperlaneEnvironment, + InterceptorConfig, MultiProvider, OverheadIgpConfig, } from '@hyperlane-xyz/sdk'; @@ -37,7 +37,7 @@ export type EnvironmentConfig = { // Each AgentConfig, keyed by the context agents: Partial>; core: ChainMap; - hooks: ChainMap; + hooks?: ChainMap; igp: ChainMap; owners: ChainMap
; infra: InfrastructureConfig; diff --git a/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts b/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts index 7eabba3496..e2b63c5866 100644 --- a/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts +++ b/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts @@ -1,4 +1,4 @@ -import { objFilter } from '@hyperlane-xyz/utils'; +import { Address, objFilter } from '@hyperlane-xyz/utils'; import { HyperlaneContracts, @@ -13,37 +13,37 @@ import { MultiProvider } from '../providers/MultiProvider'; import { ChainMap, ChainName } from '../types'; import { isHookConfig } from './config'; -import { PostDispatchHookConfig } from './types'; +import { InterceptorConfig } from './types'; export abstract class HyperlaneInterceptorDeployer< - HookConfig extends PostDispatchHookConfig, + Config extends InterceptorConfig, HookFactories extends HyperlaneFactories, -> extends HyperlaneDeployer { +> extends HyperlaneDeployer { constructor( multiProvider: MultiProvider, factories: HookFactories, + mailbox: Address, options?: DeployerOptions, ) { super(multiProvider, factories, options); } async deploy( - configMap: ChainMap, + configMap: ChainMap, ): Promise> { // TODO: uncomment when ISMs are implemented - // const ismConfigMap = objFilter( - // configMap, - // (_, config: IsmConfig): config is IsmConfig => !isHookConfig(config), - // ); - // await super.deploy(ismConfigMap); - - // deploy Hooks next - const hookConfigMap = objFilter( + const ismConfigMap = objFilter( configMap, - (_, config: HookConfig): config is HookConfig => isHookConfig(config), + (_, config): config is Config => !isHookConfig(config), + ); + await super.deploy(ismConfigMap); + + const hookConfigMap = objFilter(configMap, (_, config): config is Config => + isHookConfig(config), ); await super.deploy(hookConfigMap); + // deploy Hooks next // TODO: post deploy steps // configure ISMs with authorized hooks // await promiseObjAll( @@ -62,24 +62,25 @@ export abstract class HyperlaneInterceptorDeployer< async deployContracts( chain: ChainName, - config: HookConfig, + config: Config, ): Promise> { - this.logger(`Deploying ${config.hookContractType} on ${chain}`); if (isHookConfig(config)) { return this.deployHookContracts(chain, config); } else { - throw new Error('ISM as object unimplemented'); + return this.deployIsmContracts(chain, config); } } protected abstract deployHookContracts( chain: ChainName, - config: HookConfig, + config: Config, + mailbox?: Address, + ): Promise>; + + protected abstract deployIsmContracts( + chain: ChainName, + config: Config, ): Promise>; - // protected abstract deployIsmContracts( - // chain: ChainName, - // config: IsmConfig, - // ): Promise>; - // } + // protected abstract matchConfig(chain: ChainName, config: HookConfig): boolean; } diff --git a/typescript/sdk/src/hook/MerkleHookDeployer.ts b/typescript/sdk/src/hook/MerkleHookDeployer.ts deleted file mode 100644 index d2a10d56c8..0000000000 --- a/typescript/sdk/src/hook/MerkleHookDeployer.ts +++ /dev/null @@ -1,42 +0,0 @@ -import debug from 'debug'; - -import { MerkleTreeHook__factory } from '@hyperlane-xyz/core'; - -import { HyperlaneContracts } from '../contracts/types'; -import { MultiProvider } from '../providers/MultiProvider'; -import { ChainName } from '../types'; - -import { HyperlaneInterceptorDeployer } from './HyperlaneInterceptorDeployer'; -import { MerkleRootHookFactories } from './contracts'; -import { MerkleTreeHookConfig } from './types'; - -export class MerkleTreeInterceptorDeployer extends HyperlaneInterceptorDeployer< - MerkleTreeHookConfig, - MerkleRootHookFactories -> { - constructor( - multiProvider: MultiProvider, - factories: MerkleRootHookFactories, - ) { - super(multiProvider, factories, { - logger: debug('hyperlane:MerkleTreeInterceptorDeployer'), - }); - } - - async deployHookContracts( - chain: ChainName, - config: MerkleTreeHookConfig, - ): Promise> { - this.logger(`Deploying Merkle Tree Hook to ${chain}`); - const merkleTreeFactory = new MerkleTreeHook__factory(); - const merkleTreeHook = await this.multiProvider.handleDeploy( - chain, - merkleTreeFactory, - [config.mailbox], - ); - - return { - hook: merkleTreeHook, - }; - } -} diff --git a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts new file mode 100644 index 0000000000..56a66970d3 --- /dev/null +++ b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts @@ -0,0 +1,65 @@ +import debug from 'debug'; + +import { MerkleTreeHook__factory } from '@hyperlane-xyz/core'; +import { Address } from '@hyperlane-xyz/utils'; + +import { HyperlaneContracts } from '../contracts/types'; +import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; +import { MultisigIsmConfig } from '../ism/types'; +import { MultiProvider } from '../providers/MultiProvider'; +import { ChainName } from '../types'; + +import { HyperlaneInterceptorDeployer } from './HyperlaneInterceptorDeployer'; +import { + MerkleRootHookFactories, + MerkleRootInterceptorFactories, + MerkleRootIsmFactories, + merkleRootHookFactories, +} from './contracts'; +import { MerkleRootInterceptorConfig, MerkleTreeHookConfig } from './types'; + +export class MerkleRootInterceptorDeployer extends HyperlaneInterceptorDeployer< + MerkleRootInterceptorConfig, + MerkleRootInterceptorFactories +> { + constructor( + multiProvider: MultiProvider, + readonly ismFactory: HyperlaneIsmFactory, + readonly mailbox: Address, + ) { + super(multiProvider, merkleRootHookFactories, mailbox, { + logger: debug('hyperlane:MerkleTreeInterceptorDeployer'), + }); + } + + async deployHookContracts( + chain: ChainName, + _: MerkleTreeHookConfig, + ): Promise> { + this.logger(`Deploying Merkle Tree Hook to ${chain}`); + const merkleTreeFactory = new MerkleTreeHook__factory(); + const merkleTreeHook = await this.multiProvider.handleDeploy( + chain, + merkleTreeFactory, + [this.mailbox], + ); + + return { + hook: merkleTreeHook, + }; + } + + async deployIsmContracts( + chain: ChainName, + config: MultisigIsmConfig, + ): Promise> { + const ism = await this.ismFactory.deployMerkleRootMultisigIsm( + chain, + config, + ); + + return { + ism: ism, + }; + } +} diff --git a/typescript/sdk/src/hook/config.ts b/typescript/sdk/src/hook/config.ts index 056373003f..f8e7de3a9e 100644 --- a/typescript/sdk/src/hook/config.ts +++ b/typescript/sdk/src/hook/config.ts @@ -1,6 +1,11 @@ -import { HookContractType, PostDispatchHookConfig } from './types'; +import { + HookContractType, + InterceptorConfig, + PostDispatchHookConfig, +} from './types'; +// TODO: what is a hook config was an address? export const isHookConfig = ( - config: PostDispatchHookConfig, + config: InterceptorConfig, ): config is PostDispatchHookConfig => - config.hookContractType === HookContractType.HOOK; + typeof config !== 'string' && config.type === HookContractType.HOOK; diff --git a/typescript/sdk/src/hook/contracts.ts b/typescript/sdk/src/hook/contracts.ts index e37ad796b5..40a41a4f35 100644 --- a/typescript/sdk/src/hook/contracts.ts +++ b/typescript/sdk/src/hook/contracts.ts @@ -1,7 +1,7 @@ import { MerkleTreeHook__factory, - OPStackHook__factory, OverheadIgp__factory, + StaticMerkleRootMultisigIsm__factory, StorageGasOracle__factory, } from '@hyperlane-xyz/core'; @@ -11,6 +11,7 @@ export const merkleRootHookFactories = { hook: new MerkleTreeHook__factory(), }; export type MerkleRootHookFactories = typeof merkleRootHookFactories; +export type MerkleRootIsmFactories = typeof merkleRootIsmFactories; export const igpFactories = { // interchainGasPaymaster: new InterchainGasPaymaster__factory(), @@ -19,11 +20,15 @@ export const igpFactories = { ...proxiedFactories, }; -export const opStackHookFactories = { - hook: new OPStackHook__factory(), +export const merkleRootIsmFactories = { + ism: new StaticMerkleRootMultisigIsm__factory(), }; +export type MerkleRootInterceptorFactories = + | MerkleRootHookFactories + | MerkleRootIsmFactories; + export type PostDispatchHookFactories = - | typeof opStackHookFactories + | MerkleRootInterceptorFactories | typeof merkleRootHookFactories | typeof igpFactories; diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index 054e05936f..240a9163d6 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -1,6 +1,6 @@ import type { Address } from '@hyperlane-xyz/utils'; -import type { IsmConfig } from '../ism/types'; +import type { IsmConfig, MultisigIsmConfig } from '../ism/types'; import { ChainName } from '../types'; export enum HookContractType { @@ -9,7 +9,7 @@ export enum HookContractType { } export type OpStackHookConfig = { - hookContractType: HookContractType.HOOK; + type: HookContractType.HOOK; mailbox: Address; nativeBridge: Address; remoteIsm?: Address; @@ -17,14 +17,20 @@ export type OpStackHookConfig = { }; export type MerkleTreeHookConfig = { - hookContractType: HookContractType.HOOK; + type: HookContractType.HOOK; mailbox: Address; }; -export type PostDispatchHookConfig = OpStackHookConfig | MerkleTreeHookConfig; +export type MerkleRootInterceptorConfig = + | MerkleTreeHookConfig + | MultisigIsmConfig; + +export type PostDispatchHookConfig = + | OpStackHookConfig + | MerkleRootInterceptorConfig; export type NoMetadataIsmConfig = { - hookContractType: HookContractType.ISM; + type: HookContractType.ISM; nativeBridge: Address; }; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 5dd46c9376..01d7042e96 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -109,10 +109,13 @@ export { OverheadIgpConfig, } from './gas/types'; export { HyperlaneInterceptorDeployer } from './hook/HyperlaneInterceptorDeployer'; +export { MerkleRootInterceptorDeployer } from './hook/MerkleRootInterceptorDeployer'; export { HookContractType, InterceptorConfig, + MerkleTreeHookConfig, NoMetadataIsmConfig, + OpStackHookConfig, PostDispatchHookConfig, } from './hook/types'; export { diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index dbbd3c1430..7b2863d50f 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -9,6 +9,8 @@ import { IRoutingIsm__factory, StaticAggregationIsm__factory, StaticMOfNAddressSetFactory, + StaticMerkleRootMultisigIsm, + StaticMerkleRootMultisigIsm__factory, } from '@hyperlane-xyz/core'; import { Address, eqAddress, formatMessage, warn } from '@hyperlane-xyz/utils'; @@ -122,6 +124,24 @@ export class HyperlaneIsmFactory extends HyperlaneApp { return IMultisigIsm__factory.connect(address, signer); } + public async deployMerkleRootMultisigIsm( + chain: ChainName, + config: MultisigIsmConfig, + ): Promise { + const signer = this.multiProvider.getSigner(chain); + const multisigIsmFactory = + this.getContracts(chain).merkleRootMultisigIsmFactory; + + const address = await this.deployMOfNFactory( + chain, + multisigIsmFactory, + config.validators, + config.threshold, + ); + + return StaticMerkleRootMultisigIsm__factory.connect(address, signer); + } + private async deployRoutingIsm(chain: ChainName, config: RoutingIsmConfig) { const signer = this.multiProvider.getSigner(chain); const routingIsmFactory = this.getContracts(chain).routingIsmFactory; From 15d7a50ebc4ece39113446c4941ffa0996c759a9 Mon Sep 17 00:00:00 2001 From: -f Date: Wed, 27 Sep 2023 12:47:11 -0400 Subject: [PATCH 03/18] op stack with postDeploy --- .../infra/config/environments/test/hooks.ts | 12 ++++++ typescript/infra/scripts/deploy.ts | 22 ++++------ .../src/hook/HyperlaneInterceptorDeployer.ts | 42 +++++++++++-------- .../src/hook/MerkleRootInterceptorDeployer.ts | 6 +-- typescript/sdk/src/hook/contracts.ts | 34 --------------- typescript/sdk/src/hook/types.ts | 13 ++++-- typescript/sdk/src/index.ts | 1 + 7 files changed, 59 insertions(+), 71 deletions(-) delete mode 100644 typescript/sdk/src/hook/contracts.ts diff --git a/typescript/infra/config/environments/test/hooks.ts b/typescript/infra/config/environments/test/hooks.ts index e86bed2911..4eccab77e4 100644 --- a/typescript/infra/config/environments/test/hooks.ts +++ b/typescript/infra/config/environments/test/hooks.ts @@ -33,3 +33,15 @@ // } // }, // ); + +// merkleRootHook +// const mrConfig: ChainMap = { +// test1: { +// type: HookContractType.HOOK, +// }, +// test2: { +// type: ModuleType.MERKLE_ROOT_MULTISIG, +// validators: defaultMultisigIsmConfigs.optimism.validators, +// threshold: defaultMultisigIsmConfigs.optimism.threshold, +// }, +// }; diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index 026944dab3..bc76ec2207 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -1,3 +1,4 @@ +import { BigNumber } from 'ethers'; import path from 'path'; import { HelloWorldDeployer } from '@hyperlane-xyz/helloworld'; @@ -13,9 +14,7 @@ import { InterchainAccountDeployer, InterchainQueryDeployer, LiquidityLayerDeployer, - MerkleRootInterceptorDeployer, - ModuleType, - defaultMultisigIsmConfigs, + OpStackInterceptorDeployer, } from '@hyperlane-xyz/sdk'; import { HookContractType } from '@hyperlane-xyz/sdk/src'; import { objMap } from '@hyperlane-xyz/utils'; @@ -90,23 +89,20 @@ async function main() { const mrConfig: ChainMap = { test1: { type: HookContractType.HOOK, - mailbox: '0xb7f8bc63bbcad18155201308c8f3540b07f84f5e', + destinationDomain: BigNumber.from(10), + destination: 'test2', + nativeBridge: '0xa85233c63b9ee964add6f2cffe00fd84eb32338f', }, test2: { - type: ModuleType.MERKLE_ROOT_MULTISIG, - validators: defaultMultisigIsmConfigs.optimism.validators, - threshold: defaultMultisigIsmConfigs.optimism.threshold, + type: HookContractType.ISM, + origin: 'test1', + nativeBridge: '0x322813fd9a801c5507c9de605d63cea4f2ce6c44', }, }; config = mrConfig; - const ismFactory = HyperlaneIsmFactory.fromAddressesMap( - getAddresses(environment, Modules.ISM_FACTORY), - multiProvider, - ); - deployer = new MerkleRootInterceptorDeployer( + deployer = new OpStackInterceptorDeployer( multiProvider, - ismFactory, '0xb7f8bc63bbcad18155201308c8f3540b07f84f5e', ); // throw new Error('Hook deployment unimplemented'); diff --git a/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts b/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts index e2b63c5866..a5e74b5c06 100644 --- a/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts +++ b/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts @@ -1,4 +1,9 @@ -import { Address, objFilter } from '@hyperlane-xyz/utils'; +import { + Address, + objFilter, + objMap, + promiseObjAll, +} from '@hyperlane-xyz/utils'; import { HyperlaneContracts, @@ -15,14 +20,17 @@ import { ChainMap, ChainName } from '../types'; import { isHookConfig } from './config'; import { InterceptorConfig } from './types'; +export interface HookOptions { + remoteIsm?: Address; +} + export abstract class HyperlaneInterceptorDeployer< Config extends InterceptorConfig, HookFactories extends HyperlaneFactories, > extends HyperlaneDeployer { constructor( - multiProvider: MultiProvider, + protected readonly multiProvider: MultiProvider, factories: HookFactories, - mailbox: Address, options?: DeployerOptions, ) { super(multiProvider, factories, options); @@ -31,32 +39,27 @@ export abstract class HyperlaneInterceptorDeployer< async deploy( configMap: ChainMap, ): Promise> { - // TODO: uncomment when ISMs are implemented const ismConfigMap = objFilter( configMap, (_, config): config is Config => !isHookConfig(config), ); + this.logger(`Deploying ISM contracts to ${Object.keys(ismConfigMap)}`); await super.deploy(ismConfigMap); const hookConfigMap = objFilter(configMap, (_, config): config is Config => isHookConfig(config), ); + this.logger(`Deploying hook contracts to ${Object.keys(hookConfigMap)}`); await super.deploy(hookConfigMap); - // deploy Hooks next - // TODO: post deploy steps - // configure ISMs with authorized hooks - // await promiseObjAll( - // objMap(hookConfigMap, (hookChain, hookConfig) => { - // const hookAddress = this.deployedContracts[hookChain].hook.address; - // const ism = this.deployedContracts[hookConfig.destination].ism; - // return this.multiProvider.handleTx( - // hookConfig.destination, - // ism.setAuthorizedHook(hookAddress), - // ); - // }), - // ); + // post deploy actions (e.g. setting up authored hook) + await promiseObjAll( + objMap(ismConfigMap, (chain, config) => { + return this.postDeploy(chain, config); + }), + ); + this.logger('Interceptor deployment finished successfully'); return this.deployedContracts; } @@ -74,7 +77,6 @@ export abstract class HyperlaneInterceptorDeployer< protected abstract deployHookContracts( chain: ChainName, config: Config, - mailbox?: Address, ): Promise>; protected abstract deployIsmContracts( @@ -82,5 +84,9 @@ export abstract class HyperlaneInterceptorDeployer< config: Config, ): Promise>; + protected postDeploy(__: ChainName, _: Config): Promise { + return Promise.resolve(); + } + // protected abstract matchConfig(chain: ChainName, config: HookConfig): boolean; } diff --git a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts index 56a66970d3..f542597b1b 100644 --- a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts +++ b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts @@ -15,7 +15,7 @@ import { MerkleRootInterceptorFactories, MerkleRootIsmFactories, merkleRootHookFactories, -} from './contracts'; +} from './contracts/merkleRoot'; import { MerkleRootInterceptorConfig, MerkleTreeHookConfig } from './types'; export class MerkleRootInterceptorDeployer extends HyperlaneInterceptorDeployer< @@ -27,7 +27,7 @@ export class MerkleRootInterceptorDeployer extends HyperlaneInterceptorDeployer< readonly ismFactory: HyperlaneIsmFactory, readonly mailbox: Address, ) { - super(multiProvider, merkleRootHookFactories, mailbox, { + super(multiProvider, merkleRootHookFactories, { logger: debug('hyperlane:MerkleTreeInterceptorDeployer'), }); } @@ -45,7 +45,7 @@ export class MerkleRootInterceptorDeployer extends HyperlaneInterceptorDeployer< ); return { - hook: merkleTreeHook, + merkleRootHook: merkleTreeHook, }; } diff --git a/typescript/sdk/src/hook/contracts.ts b/typescript/sdk/src/hook/contracts.ts deleted file mode 100644 index 40a41a4f35..0000000000 --- a/typescript/sdk/src/hook/contracts.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - MerkleTreeHook__factory, - OverheadIgp__factory, - StaticMerkleRootMultisigIsm__factory, - StorageGasOracle__factory, -} from '@hyperlane-xyz/core'; - -import { proxiedFactories } from '../router/types'; - -export const merkleRootHookFactories = { - hook: new MerkleTreeHook__factory(), -}; -export type MerkleRootHookFactories = typeof merkleRootHookFactories; -export type MerkleRootIsmFactories = typeof merkleRootIsmFactories; - -export const igpFactories = { - // interchainGasPaymaster: new InterchainGasPaymaster__factory(), - interchainGasPaymaster: new OverheadIgp__factory(), - storageGasOracle: new StorageGasOracle__factory(), - ...proxiedFactories, -}; - -export const merkleRootIsmFactories = { - ism: new StaticMerkleRootMultisigIsm__factory(), -}; - -export type MerkleRootInterceptorFactories = - | MerkleRootHookFactories - | MerkleRootIsmFactories; - -export type PostDispatchHookFactories = - | MerkleRootInterceptorFactories - | typeof merkleRootHookFactories - | typeof igpFactories; diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index 240a9163d6..c0ec148da9 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -1,3 +1,5 @@ +import { BigNumber } from 'ethers'; + import type { Address } from '@hyperlane-xyz/utils'; import type { IsmConfig, MultisigIsmConfig } from '../ism/types'; @@ -10,28 +12,33 @@ export enum HookContractType { export type OpStackHookConfig = { type: HookContractType.HOOK; - mailbox: Address; nativeBridge: Address; remoteIsm?: Address; + destinationDomain: BigNumber; destination: ChainName; }; export type MerkleTreeHookConfig = { type: HookContractType.HOOK; - mailbox: Address; }; export type MerkleRootInterceptorConfig = | MerkleTreeHookConfig | MultisigIsmConfig; +export type OpStackInterceptorConfig = OpStackHookConfig | NoMetadataIsmConfig; + export type PostDispatchHookConfig = | OpStackHookConfig | MerkleRootInterceptorConfig; export type NoMetadataIsmConfig = { type: HookContractType.ISM; + origin: ChainName; nativeBridge: Address; }; -export type InterceptorConfig = PostDispatchHookConfig | IsmConfig; +export type InterceptorConfig = + | PostDispatchHookConfig + | IsmConfig + | NoMetadataIsmConfig; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 01d7042e96..8b38768d70 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -110,6 +110,7 @@ export { } from './gas/types'; export { HyperlaneInterceptorDeployer } from './hook/HyperlaneInterceptorDeployer'; export { MerkleRootInterceptorDeployer } from './hook/MerkleRootInterceptorDeployer'; +export { OpStackInterceptorDeployer } from './hook/OpStackInterceptorDeployer'; export { HookContractType, InterceptorConfig, From 92ce7f16c86a208c27a6a0e2841aceb68e041cad Mon Sep 17 00:00:00 2001 From: -f Date: Wed, 27 Sep 2023 13:15:54 -0400 Subject: [PATCH 04/18] add console --- .../src/hook/MerkleRootInterceptorDeployer.ts | 4 +- .../src/hook/OpStackInterceptorDeployer.ts | 105 ++++++++++++++++++ .../sdk/src/hook/contracts/merkleRoot.ts | 19 ++++ typescript/sdk/src/hook/contracts/opStack.ts | 16 +++ typescript/sdk/src/ism/HyperlaneIsmFactory.ts | 1 + 5 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 typescript/sdk/src/hook/OpStackInterceptorDeployer.ts create mode 100644 typescript/sdk/src/hook/contracts/merkleRoot.ts create mode 100644 typescript/sdk/src/hook/contracts/opStack.ts diff --git a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts index f542597b1b..b0f6602ef9 100644 --- a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts +++ b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts @@ -36,14 +36,14 @@ export class MerkleRootInterceptorDeployer extends HyperlaneInterceptorDeployer< chain: ChainName, _: MerkleTreeHookConfig, ): Promise> { - this.logger(`Deploying Merkle Tree Hook to ${chain}`); + this.logger(`Deploying MerkleRootHook to ${chain}`); const merkleTreeFactory = new MerkleTreeHook__factory(); const merkleTreeHook = await this.multiProvider.handleDeploy( chain, merkleTreeFactory, [this.mailbox], ); - + this.logger(`MerkleRootHook successfully deployed on ${chain}`); return { merkleRootHook: merkleTreeHook, }; diff --git a/typescript/sdk/src/hook/OpStackInterceptorDeployer.ts b/typescript/sdk/src/hook/OpStackInterceptorDeployer.ts new file mode 100644 index 0000000000..c2aaa02025 --- /dev/null +++ b/typescript/sdk/src/hook/OpStackInterceptorDeployer.ts @@ -0,0 +1,105 @@ +import debug from 'debug'; + +import { OPStackHook__factory, OPStackIsm__factory } from '@hyperlane-xyz/core'; +import { Address } from '@hyperlane-xyz/utils'; + +import { HyperlaneContracts } from '../contracts/types'; +import { MultiProvider } from '../providers/MultiProvider'; +import { ChainName } from '../types'; + +import { HyperlaneInterceptorDeployer } from './HyperlaneInterceptorDeployer'; +import { + OpStackHookFactories, + OpStackInterceptorFactories, + OpStackIsmFactories, + opStackHookFactories, + opStackIsmFactories, +} from './contracts/opStack'; +import { + NoMetadataIsmConfig, + OpStackHookConfig, + OpStackInterceptorConfig, +} from './types'; + +export class OpStackInterceptorDeployer extends HyperlaneInterceptorDeployer< + OpStackInterceptorConfig, + OpStackInterceptorFactories +> { + constructor(multiProvider: MultiProvider, readonly mailbox: Address) { + super( + multiProvider, + { ...opStackIsmFactories, ...opStackHookFactories }, + { + logger: debug('hyperlane:OpStackInteceptorDeployer'), + }, + ); + } + + async deployHookContracts( + chain: ChainName, + config: OpStackHookConfig, + ): Promise> { + this.logger(`Deploying OpStackHook to ${chain}`); + const opStackHookFactory = new OPStackHook__factory(); + if ( + !this.deployedContracts[config.destination] || + !( + this.deployedContracts[ + config.destination + ] as HyperlaneContracts + ).opStackIsm + ) { + throw new Error(`OpStackIsm not deployed on ${config.destination}`); + } + const ism = ( + this.deployedContracts[ + config.destination + ] as HyperlaneContracts + ).opStackIsm.address; + + const opStackHook = await this.multiProvider.handleDeploy( + chain, + opStackHookFactory, + [this.mailbox, config.destinationDomain, config.nativeBridge, ism], + ); + this.logger(`OpStackHook successfully deployed on ${chain}`); + return { + opStackHook: opStackHook, + }; + } + + async deployIsmContracts( + chain: ChainName, + config: NoMetadataIsmConfig, + ): Promise> { + this.logger(`Deploying OpStackIsm to ${chain}`); + const opStackIsmFactory = new OPStackIsm__factory(); + const opStackIsm = await this.multiProvider.handleDeploy( + chain, + opStackIsmFactory, + [config.nativeBridge], + ); + this.logger(`OpStackIsm successfully deployed on ${chain}`); + return { + opStackIsm: opStackIsm, + }; + } + + async postDeploy(chain: string, config: NoMetadataIsmConfig): Promise { + this.logger(`Setting authorized hook for ISM on ${chain}`); + const hookAddress = ( + this.deployedContracts[ + config.origin + ] as HyperlaneContracts + ).opStackHook.address; + const ism = ( + this.deployedContracts[chain] as HyperlaneContracts + ).opStackIsm; + + await this.multiProvider.handleTx( + chain, + ism.setAuthorizedHook(hookAddress), + ); + this.logger(`Authorized hook set successfully to ${hookAddress}`); + } +} diff --git a/typescript/sdk/src/hook/contracts/merkleRoot.ts b/typescript/sdk/src/hook/contracts/merkleRoot.ts new file mode 100644 index 0000000000..ea0280c486 --- /dev/null +++ b/typescript/sdk/src/hook/contracts/merkleRoot.ts @@ -0,0 +1,19 @@ +import { + MerkleTreeHook__factory, + StaticMerkleRootMultisigIsm__factory, +} from '@hyperlane-xyz/core'; + +export const merkleRootHookFactories = { + merkleRootHook: new MerkleTreeHook__factory(), +}; + +export type MerkleRootHookFactories = typeof merkleRootHookFactories; +export type MerkleRootIsmFactories = typeof merkleRootIsmFactories; + +export const merkleRootIsmFactories = { + ism: new StaticMerkleRootMultisigIsm__factory(), +}; + +export type MerkleRootInterceptorFactories = + | MerkleRootHookFactories + | MerkleRootIsmFactories; diff --git a/typescript/sdk/src/hook/contracts/opStack.ts b/typescript/sdk/src/hook/contracts/opStack.ts new file mode 100644 index 0000000000..69f70f5986 --- /dev/null +++ b/typescript/sdk/src/hook/contracts/opStack.ts @@ -0,0 +1,16 @@ +import { OPStackHook__factory, OPStackIsm__factory } from '@hyperlane-xyz/core'; + +export const opStackHookFactories = { + opStackHook: new OPStackHook__factory(), +}; +export type OpStackHookFactories = typeof opStackHookFactories; + +export const opStackIsmFactories = { + opStackIsm: new OPStackIsm__factory(), +}; + +export type OpStackIsmFactories = typeof opStackIsmFactories; + +export type OpStackInterceptorFactories = + | OpStackHookFactories + | OpStackIsmFactories; diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index 7b2863d50f..061455700c 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -128,6 +128,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { chain: ChainName, config: MultisigIsmConfig, ): Promise { + this.logger(`Deploying Merkle Root Multisig ISM to ${chain}`); const signer = this.multiProvider.getSigner(chain); const multisigIsmFactory = this.getContracts(chain).merkleRootMultisigIsmFactory; From 77060cc7b6aeb1dc8cc80d5e1826b34f857e65e5 Mon Sep 17 00:00:00 2001 From: -f Date: Thu, 28 Sep 2023 10:12:18 -0400 Subject: [PATCH 05/18] merkle standalone --- typescript/infra/config/aggregationIsm.ts | 35 +---- .../config/environments/mainnet2/hooks.ts | 6 +- .../infra/config/environments/test/hooks.ts | 47 ------ .../infra/config/environments/test/index.ts | 3 +- .../config/environments/test/interceptor.ts | 36 +++++ typescript/infra/config/multisigIsm.ts | 144 ++++++------------ .../infra/config/rcMultisigIsmConfigs.ts | 96 ++++++++++++ typescript/infra/scripts/deploy.ts | 42 ++--- .../src/hook/HyperlaneInterceptorDeployer.ts | 92 ----------- .../src/hook/MerkleRootInterceptorDeployer.ts | 35 +++-- .../src/hook/OpStackInterceptorDeployer.ts | 105 ------------- typescript/sdk/src/hook/config.ts | 11 -- .../{contracts/merkleRoot.ts => contracts.ts} | 12 +- typescript/sdk/src/hook/contracts/opStack.ts | 16 -- typescript/sdk/src/hook/types.ts | 33 ++-- typescript/sdk/src/index.ts | 8 +- typescript/sdk/src/ism/HyperlaneIsmFactory.ts | 3 +- typescript/sdk/src/ism/types.ts | 4 +- 18 files changed, 259 insertions(+), 469 deletions(-) delete mode 100644 typescript/infra/config/environments/test/hooks.ts create mode 100644 typescript/infra/config/environments/test/interceptor.ts create mode 100644 typescript/infra/config/rcMultisigIsmConfigs.ts delete mode 100644 typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts delete mode 100644 typescript/sdk/src/hook/OpStackInterceptorDeployer.ts delete mode 100644 typescript/sdk/src/hook/config.ts rename typescript/sdk/src/hook/{contracts/merkleRoot.ts => contracts.ts} (55%) delete mode 100644 typescript/sdk/src/hook/contracts/opStack.ts diff --git a/typescript/infra/config/aggregationIsm.ts b/typescript/infra/config/aggregationIsm.ts index 6807bf37f9..945886498c 100644 --- a/typescript/infra/config/aggregationIsm.ts +++ b/typescript/infra/config/aggregationIsm.ts @@ -1,32 +1,21 @@ import { AggregationIsmConfig, - ChainMap, ChainName, Chains, IsmConfig, ModuleType, MultisigIsmConfig, RoutingIsmConfig, - defaultMultisigIsmConfigs, } from '@hyperlane-xyz/sdk'; -import { Address, objFilter, objMap } from '@hyperlane-xyz/utils'; +import { Address } from '@hyperlane-xyz/utils'; import { DeployEnvironment } from '../src/config'; import { Contexts } from './contexts'; -import { supportedChainNames as mainnet2Chains } from './environments/mainnet2/chains'; import { owners as mainnet2Owners } from './environments/mainnet2/owners'; -import { chainNames as testChains } from './environments/test/chains'; import { owners as testOwners } from './environments/test/owners'; -import { supportedChainNames as testnet3Chains } from './environments/testnet3/chains'; import { owners as testnet3Owners } from './environments/testnet3/owners'; -import { rcMultisigIsmConfigs } from './multisigIsm'; - -const chains = { - mainnet2: mainnet2Chains, - testnet3: testnet3Chains, - test: testChains, -}; +import { multisigIsms } from './multisigIsm'; const owners = { testnet3: testnet3Owners, @@ -34,26 +23,6 @@ const owners = { test: testOwners, }; -export const multisigIsms = ( - env: DeployEnvironment, - local: ChainName, - type: MultisigIsmConfig['type'], - context: Contexts, -): ChainMap => - objMap( - objFilter( - context === Contexts.ReleaseCandidate - ? rcMultisigIsmConfigs - : defaultMultisigIsmConfigs, - (chain, config): config is MultisigIsmConfig => - chain !== local && chains[env].includes(chain), - ), - (_, config) => ({ - ...config, - type, - }), - ); - /// Routing => Multisig ISM type export const routingIsm = ( environment: DeployEnvironment, diff --git a/typescript/infra/config/environments/mainnet2/hooks.ts b/typescript/infra/config/environments/mainnet2/hooks.ts index 8827d5121b..20e334f8d6 100644 --- a/typescript/infra/config/environments/mainnet2/hooks.ts +++ b/typescript/infra/config/environments/mainnet2/hooks.ts @@ -1,6 +1,6 @@ // import { // ChainMap, -// HookContractType, +// InterceptorType, // InterceptorConfig, // NoMetadataIsmConfig, // OpStackHookConfig, @@ -18,7 +18,7 @@ // (chain) => { // if (chain === 'ethereum') { // const hookConfig: OpStackHookConfig = { -// hookContractType: HookContractType.HOOK, +// InterceptorType: InterceptorType.HOOK, // mailbox: '0x23', // nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1', // remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first @@ -27,7 +27,7 @@ // return hookConfig; // } else { // const ismConfig: NoMetadataIsmConfig = { -// hookContractType: HookContractType.ISM, +// InterceptorType: InterceptorType.ISM, // nativeBridge: '0x4200000000000000000000000000000000000007', // }; // return ismConfig; diff --git a/typescript/infra/config/environments/test/hooks.ts b/typescript/infra/config/environments/test/hooks.ts deleted file mode 100644 index 4eccab77e4..0000000000 --- a/typescript/infra/config/environments/test/hooks.ts +++ /dev/null @@ -1,47 +0,0 @@ -// import { -// ChainMap, -// HookContractType, -// InterceptorConfig, -// NoMetadataIsmConfig, -// OpStackHookConfig, -// filterByChains, -// } from '@hyperlane-xyz/sdk'; -// import { objMap } from '@hyperlane-xyz/utils'; - -// import { owners } from './owners'; - -// const chainNameFilter = new Set(['test1', 'test2']); -// const filteredOwnersResult = filterByChains(owners, chainNameFilter); - -// export const hooks: ChainMap = objMap( -// filteredOwnersResult, -// (chain) => { -// if (chain === 'test1') { -// const hookConfig: OpStackHookConfig = { -// hookContractType: HookContractType.HOOK, -// nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1', -// remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first -// destination: 'test2', -// }; -// return hookConfig; -// } else { -// const ismConfig: NoMetadataIsmConfig = { -// hookContractType: HookContractType.ISM, -// nativeBridge: '0x4200000000000000000000000000000000000007', -// }; -// return ismConfig; -// } -// }, -// ); - -// merkleRootHook -// const mrConfig: ChainMap = { -// test1: { -// type: HookContractType.HOOK, -// }, -// test2: { -// type: ModuleType.MERKLE_ROOT_MULTISIG, -// validators: defaultMultisigIsmConfigs.optimism.validators, -// threshold: defaultMultisigIsmConfigs.optimism.threshold, -// }, -// }; diff --git a/typescript/infra/config/environments/test/index.ts b/typescript/infra/config/environments/test/index.ts index d0a3c7dac3..bd776d8308 100644 --- a/typescript/infra/config/environments/test/index.ts +++ b/typescript/infra/config/environments/test/index.ts @@ -11,6 +11,7 @@ import { storageGasOracleConfig } from './gas-oracle'; // import { hooks } from './hooks'; import { igp } from './igp'; import { infra } from './infra'; +import { merkleRoot } from './interceptor'; import { owners } from './owners'; export const environment: EnvironmentConfig = { @@ -18,7 +19,7 @@ export const environment: EnvironmentConfig = { chainMetadataConfigs: testConfigs, agents, core, - // hooks, + hooks: merkleRoot, igp, owners, infra, diff --git a/typescript/infra/config/environments/test/interceptor.ts b/typescript/infra/config/environments/test/interceptor.ts new file mode 100644 index 0000000000..d2da41cf59 --- /dev/null +++ b/typescript/infra/config/environments/test/interceptor.ts @@ -0,0 +1,36 @@ +import { + ChainMap, + InterceptorConfig, + InterceptorType, +} from '@hyperlane-xyz/sdk'; +import { objMap } from '@hyperlane-xyz/utils'; + +import { merkleRootMultisig } from './multisigIsm'; +import { owners } from './owners'; + +export const merkleRoot: ChainMap = objMap( + owners, + (chain, _) => { + const config: InterceptorConfig = { + hook: { + type: InterceptorType.HOOK, + }, + ism: merkleRootMultisig(chain), + }; + return config; + }, +); + +// const mrConfig: ChainMap = { +// test1: { +// type: InterceptorType.HOOK, +// destinationDomain: BigNumber.from(10), +// destination: 'test2', +// nativeBridge: '0xa85233c63b9ee964add6f2cffe00fd84eb32338f', +// }, +// test2: { +// type: InterceptorType.ISM, +// origin: 'test1', +// nativeBridge: '0x322813fd9a801c5507c9de605d63cea4f2ce6c44', +// }, +// }; diff --git a/typescript/infra/config/multisigIsm.ts b/typescript/infra/config/multisigIsm.ts index e787b9e65c..18d1b40f23 100644 --- a/typescript/infra/config/multisigIsm.ts +++ b/typescript/infra/config/multisigIsm.ts @@ -1,96 +1,52 @@ -import { ChainMap, MultisigConfig } from '@hyperlane-xyz/sdk'; +import { + ChainMap, + ChainName, + MultisigIsmConfig, + defaultMultisigIsmConfigs, +} from '@hyperlane-xyz/sdk'; +import { objFilter, objMap } from '@hyperlane-xyz/utils'; -export const rcMultisigIsmConfigs: ChainMap = { - // ----------------- Mainnets ----------------- - celo: { - threshold: 1, - validators: [ - '0xe7a82e210f512f8e9900d6bc2acbf7981c63e66e', // abacus - ], - }, - ethereum: { - threshold: 1, - validators: [ - '0xaea1adb1c687b061e5b60b9da84cb69e7b5fab44', // abacus - ], - }, - avalanche: { - threshold: 1, - validators: [ - '0x706976391e23dea28152e0207936bd942aba01ce', // abacus - ], - }, - polygon: { - threshold: 1, - validators: [ - '0xef372f6ff7775989b3ac884506ee31c79638c989', // abacus - ], - }, - bsc: { - threshold: 1, - validators: [ - '0x0823081031a4a6f97c6083775c191d17ca96d0ab', // abacus - ], - }, - arbitrum: { - threshold: 1, - validators: [ - '0x1a95b35fb809d57faf1117c1cc29a6c5df289df1', // abacus - ], - }, - optimism: { - threshold: 1, - validators: [ - '0x60e938bf280bbc21bacfd8bf435459d9003a8f98', // abacus - ], - }, - moonbeam: { - threshold: 1, - validators: [ - '0x0df7140811e309dc69638352545151ebb9d5e0fd', // abacus - ], - }, - gnosis: { - threshold: 1, - validators: [ - '0x15f48e78092a4f79febface509cfd76467c6cdbb', // abacus - ], - }, - // ----------------- Testnets ----------------- - alfajores: { - threshold: 1, - validators: ['0x45e5c228b38e1cf09e9a3423ed0cf4862c4bf3de'], - }, - fuji: { - threshold: 1, - validators: ['0xd81ba169170a9b582812cf0e152d2c168572e21f'], - }, - mumbai: { - threshold: 1, - validators: ['0xb537c4ce34e1cad718be52aa30b095e416eae46a'], - }, - bsctestnet: { - threshold: 1, - validators: ['0x77f80ef5b18977e15d81aea8dd3a88e7df4bc0eb'], - }, - goerli: { - threshold: 1, - validators: ['0x9597ddb4ad2af237665559574b820596bb77ae7a'], - }, - sepolia: { - threshold: 1, - validators: ['0x183f15924f3a464c54c9393e8d268eb44d2b208c'], - }, - moonbasealpha: { - threshold: 1, - validators: ['0xbeaf158f85d7b64ced36b8aea0bbc4cd0f2d1a5d'], - }, - optimismgoerli: { - threshold: 1, - validators: ['0x1d6798671ac532f2bf30c3a5230697a4695705e4'], - }, - arbitrumgoerli: { - threshold: 1, - validators: ['0x6d13367c7cd713a4ea79a2552adf824bf1ecdd5e'], - }, +import { DeployEnvironment } from '../src/config'; + +import { Contexts } from './contexts'; +import { supportedChainNames as mainnet2Chains } from './environments/mainnet2/chains'; +import { chainNames as testChains } from './environments/test/chains'; +import { supportedChainNames as testnet3Chains } from './environments/testnet3/chains'; +import { rcMultisigIsmConfigs } from './rcMultisigIsmConfigs'; + +const chains = { + mainnet2: mainnet2Chains, + testnet3: testnet3Chains, + test: testChains, }; + +export const multisigIsm = ( + env: DeployEnvironment, + chain: ChainName, + type: MultisigIsmConfig['type'], + context: Contexts, +): MultisigIsmConfig => { + return context === Contexts.ReleaseCandidate + ? { ...rcMultisigIsmConfigs[chain], type } + : { ...defaultMultisigIsmConfigs[chain], type }; +}; + +export const multisigIsms = ( + env: DeployEnvironment, + local: ChainName, + type: MultisigIsmConfig['type'], + context: Contexts, +): ChainMap => + objMap( + objFilter( + context === Contexts.ReleaseCandidate + ? rcMultisigIsmConfigs + : defaultMultisigIsmConfigs, + (chain, config): config is MultisigIsmConfig => + chain !== local && chains[env].includes(chain), + ), + (_, config) => ({ + ...config, + type, + }), + ); diff --git a/typescript/infra/config/rcMultisigIsmConfigs.ts b/typescript/infra/config/rcMultisigIsmConfigs.ts new file mode 100644 index 0000000000..e787b9e65c --- /dev/null +++ b/typescript/infra/config/rcMultisigIsmConfigs.ts @@ -0,0 +1,96 @@ +import { ChainMap, MultisigConfig } from '@hyperlane-xyz/sdk'; + +export const rcMultisigIsmConfigs: ChainMap = { + // ----------------- Mainnets ----------------- + celo: { + threshold: 1, + validators: [ + '0xe7a82e210f512f8e9900d6bc2acbf7981c63e66e', // abacus + ], + }, + ethereum: { + threshold: 1, + validators: [ + '0xaea1adb1c687b061e5b60b9da84cb69e7b5fab44', // abacus + ], + }, + avalanche: { + threshold: 1, + validators: [ + '0x706976391e23dea28152e0207936bd942aba01ce', // abacus + ], + }, + polygon: { + threshold: 1, + validators: [ + '0xef372f6ff7775989b3ac884506ee31c79638c989', // abacus + ], + }, + bsc: { + threshold: 1, + validators: [ + '0x0823081031a4a6f97c6083775c191d17ca96d0ab', // abacus + ], + }, + arbitrum: { + threshold: 1, + validators: [ + '0x1a95b35fb809d57faf1117c1cc29a6c5df289df1', // abacus + ], + }, + optimism: { + threshold: 1, + validators: [ + '0x60e938bf280bbc21bacfd8bf435459d9003a8f98', // abacus + ], + }, + moonbeam: { + threshold: 1, + validators: [ + '0x0df7140811e309dc69638352545151ebb9d5e0fd', // abacus + ], + }, + gnosis: { + threshold: 1, + validators: [ + '0x15f48e78092a4f79febface509cfd76467c6cdbb', // abacus + ], + }, + // ----------------- Testnets ----------------- + alfajores: { + threshold: 1, + validators: ['0x45e5c228b38e1cf09e9a3423ed0cf4862c4bf3de'], + }, + fuji: { + threshold: 1, + validators: ['0xd81ba169170a9b582812cf0e152d2c168572e21f'], + }, + mumbai: { + threshold: 1, + validators: ['0xb537c4ce34e1cad718be52aa30b095e416eae46a'], + }, + bsctestnet: { + threshold: 1, + validators: ['0x77f80ef5b18977e15d81aea8dd3a88e7df4bc0eb'], + }, + goerli: { + threshold: 1, + validators: ['0x9597ddb4ad2af237665559574b820596bb77ae7a'], + }, + sepolia: { + threshold: 1, + validators: ['0x183f15924f3a464c54c9393e8d268eb44d2b208c'], + }, + moonbasealpha: { + threshold: 1, + validators: ['0xbeaf158f85d7b64ced36b8aea0bbc4cd0f2d1a5d'], + }, + optimismgoerli: { + threshold: 1, + validators: ['0x1d6798671ac532f2bf30c3a5230697a4695705e4'], + }, + arbitrumgoerli: { + threshold: 1, + validators: ['0x6d13367c7cd713a4ea79a2552adf824bf1ecdd5e'], + }, +}; diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index bc76ec2207..009df47f30 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -1,4 +1,3 @@ -import { BigNumber } from 'ethers'; import path from 'path'; import { HelloWorldDeployer } from '@hyperlane-xyz/helloworld'; @@ -10,13 +9,11 @@ import { HyperlaneIgpDeployer, HyperlaneIsmFactory, HyperlaneIsmFactoryDeployer, - InterceptorConfig, InterchainAccountDeployer, InterchainQueryDeployer, LiquidityLayerDeployer, - OpStackInterceptorDeployer, + MerkleRootInterceptorDeployer, } from '@hyperlane-xyz/sdk'; -import { HookContractType } from '@hyperlane-xyz/sdk/src'; import { objMap } from '@hyperlane-xyz/utils'; import { Contexts } from '../config/contexts'; @@ -78,35 +75,20 @@ async function main() { deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory); } else if (module === Modules.HOOK) { // throw new Error('Hook deployment unimplemented'); - // config = envConfig.hooks; - // deployer = new HyperlaneHookDeployer(multiProvider); - // if (envConfig.hooks) { - // config = envConfig.hooks; - // console.log('envConfig: ', config); - // deployer = new MerkleTreeInterceptorDeployer(multiProvider); - // } else { - - const mrConfig: ChainMap = { - test1: { - type: HookContractType.HOOK, - destinationDomain: BigNumber.from(10), - destination: 'test2', - nativeBridge: '0xa85233c63b9ee964add6f2cffe00fd84eb32338f', - }, - test2: { - type: HookContractType.ISM, - origin: 'test1', - nativeBridge: '0x322813fd9a801c5507c9de605d63cea4f2ce6c44', - }, - }; - - config = mrConfig; - deployer = new OpStackInterceptorDeployer( + if (!envConfig.hooks) { + throw new Error(`No hook config for ${environment}`); + } + config = envConfig.hooks; + console.log(config); + const ismFactory = HyperlaneIsmFactory.fromAddressesMap( + getAddresses(environment, Modules.ISM_FACTORY), multiProvider, + ); + deployer = new MerkleRootInterceptorDeployer( + multiProvider, + ismFactory, '0xb7f8bc63bbcad18155201308c8f3540b07f84f5e', ); - // throw new Error('Hook deployment unimplemented'); - // } } else if (module === Modules.INTERCHAIN_GAS_PAYMASTER) { config = envConfig.igp; deployer = new HyperlaneIgpDeployer(multiProvider); diff --git a/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts b/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts deleted file mode 100644 index a5e74b5c06..0000000000 --- a/typescript/sdk/src/hook/HyperlaneInterceptorDeployer.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { - Address, - objFilter, - objMap, - promiseObjAll, -} from '@hyperlane-xyz/utils'; - -import { - HyperlaneContracts, - HyperlaneContractsMap, - HyperlaneFactories, -} from '../contracts/types'; -import { - DeployerOptions, - HyperlaneDeployer, -} from '../deploy/HyperlaneDeployer'; -import { MultiProvider } from '../providers/MultiProvider'; -import { ChainMap, ChainName } from '../types'; - -import { isHookConfig } from './config'; -import { InterceptorConfig } from './types'; - -export interface HookOptions { - remoteIsm?: Address; -} - -export abstract class HyperlaneInterceptorDeployer< - Config extends InterceptorConfig, - HookFactories extends HyperlaneFactories, -> extends HyperlaneDeployer { - constructor( - protected readonly multiProvider: MultiProvider, - factories: HookFactories, - options?: DeployerOptions, - ) { - super(multiProvider, factories, options); - } - - async deploy( - configMap: ChainMap, - ): Promise> { - const ismConfigMap = objFilter( - configMap, - (_, config): config is Config => !isHookConfig(config), - ); - this.logger(`Deploying ISM contracts to ${Object.keys(ismConfigMap)}`); - await super.deploy(ismConfigMap); - - const hookConfigMap = objFilter(configMap, (_, config): config is Config => - isHookConfig(config), - ); - this.logger(`Deploying hook contracts to ${Object.keys(hookConfigMap)}`); - await super.deploy(hookConfigMap); - - // post deploy actions (e.g. setting up authored hook) - await promiseObjAll( - objMap(ismConfigMap, (chain, config) => { - return this.postDeploy(chain, config); - }), - ); - - this.logger('Interceptor deployment finished successfully'); - return this.deployedContracts; - } - - async deployContracts( - chain: ChainName, - config: Config, - ): Promise> { - if (isHookConfig(config)) { - return this.deployHookContracts(chain, config); - } else { - return this.deployIsmContracts(chain, config); - } - } - - protected abstract deployHookContracts( - chain: ChainName, - config: Config, - ): Promise>; - - protected abstract deployIsmContracts( - chain: ChainName, - config: Config, - ): Promise>; - - protected postDeploy(__: ChainName, _: Config): Promise { - return Promise.resolve(); - } - - // protected abstract matchConfig(chain: ChainName, config: HookConfig): boolean; -} diff --git a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts index b0f6602ef9..68bf2844a8 100644 --- a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts +++ b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts @@ -4,21 +4,22 @@ import { MerkleTreeHook__factory } from '@hyperlane-xyz/core'; import { Address } from '@hyperlane-xyz/utils'; import { HyperlaneContracts } from '../contracts/types'; +import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; import { MultisigIsmConfig } from '../ism/types'; import { MultiProvider } from '../providers/MultiProvider'; import { ChainName } from '../types'; -import { HyperlaneInterceptorDeployer } from './HyperlaneInterceptorDeployer'; import { MerkleRootHookFactories, MerkleRootInterceptorFactories, MerkleRootIsmFactories, merkleRootHookFactories, -} from './contracts/merkleRoot'; -import { MerkleRootInterceptorConfig, MerkleTreeHookConfig } from './types'; + merkleRootIsmFactories, +} from './contracts'; +import { MerkleRootHookConfig, MerkleRootInterceptorConfig } from './types'; -export class MerkleRootInterceptorDeployer extends HyperlaneInterceptorDeployer< +export class MerkleRootInterceptorDeployer extends HyperlaneDeployer< MerkleRootInterceptorConfig, MerkleRootInterceptorFactories > { @@ -27,14 +28,30 @@ export class MerkleRootInterceptorDeployer extends HyperlaneInterceptorDeployer< readonly ismFactory: HyperlaneIsmFactory, readonly mailbox: Address, ) { - super(multiProvider, merkleRootHookFactories, { - logger: debug('hyperlane:MerkleTreeInterceptorDeployer'), - }); + super( + multiProvider, + { ...merkleRootHookFactories, ...merkleRootIsmFactories }, + { + logger: debug('hyperlane:MerkleRootInterceptorDeployer'), + }, + ); + } + + async deployContracts( + chain: ChainName, + config: MerkleRootInterceptorConfig, + ): Promise> { + const hookContracts = await this.deployHookContracts(chain, config.hook); + const ismContracts = await this.deployIsmContracts(chain, config.ism); + return { + ...hookContracts, + ...ismContracts, + }; } async deployHookContracts( chain: ChainName, - _: MerkleTreeHookConfig, + _: MerkleRootHookConfig, ): Promise> { this.logger(`Deploying MerkleRootHook to ${chain}`); const merkleTreeFactory = new MerkleTreeHook__factory(); @@ -45,7 +62,7 @@ export class MerkleRootInterceptorDeployer extends HyperlaneInterceptorDeployer< ); this.logger(`MerkleRootHook successfully deployed on ${chain}`); return { - merkleRootHook: merkleTreeHook, + hook: merkleTreeHook, }; } diff --git a/typescript/sdk/src/hook/OpStackInterceptorDeployer.ts b/typescript/sdk/src/hook/OpStackInterceptorDeployer.ts deleted file mode 100644 index c2aaa02025..0000000000 --- a/typescript/sdk/src/hook/OpStackInterceptorDeployer.ts +++ /dev/null @@ -1,105 +0,0 @@ -import debug from 'debug'; - -import { OPStackHook__factory, OPStackIsm__factory } from '@hyperlane-xyz/core'; -import { Address } from '@hyperlane-xyz/utils'; - -import { HyperlaneContracts } from '../contracts/types'; -import { MultiProvider } from '../providers/MultiProvider'; -import { ChainName } from '../types'; - -import { HyperlaneInterceptorDeployer } from './HyperlaneInterceptorDeployer'; -import { - OpStackHookFactories, - OpStackInterceptorFactories, - OpStackIsmFactories, - opStackHookFactories, - opStackIsmFactories, -} from './contracts/opStack'; -import { - NoMetadataIsmConfig, - OpStackHookConfig, - OpStackInterceptorConfig, -} from './types'; - -export class OpStackInterceptorDeployer extends HyperlaneInterceptorDeployer< - OpStackInterceptorConfig, - OpStackInterceptorFactories -> { - constructor(multiProvider: MultiProvider, readonly mailbox: Address) { - super( - multiProvider, - { ...opStackIsmFactories, ...opStackHookFactories }, - { - logger: debug('hyperlane:OpStackInteceptorDeployer'), - }, - ); - } - - async deployHookContracts( - chain: ChainName, - config: OpStackHookConfig, - ): Promise> { - this.logger(`Deploying OpStackHook to ${chain}`); - const opStackHookFactory = new OPStackHook__factory(); - if ( - !this.deployedContracts[config.destination] || - !( - this.deployedContracts[ - config.destination - ] as HyperlaneContracts - ).opStackIsm - ) { - throw new Error(`OpStackIsm not deployed on ${config.destination}`); - } - const ism = ( - this.deployedContracts[ - config.destination - ] as HyperlaneContracts - ).opStackIsm.address; - - const opStackHook = await this.multiProvider.handleDeploy( - chain, - opStackHookFactory, - [this.mailbox, config.destinationDomain, config.nativeBridge, ism], - ); - this.logger(`OpStackHook successfully deployed on ${chain}`); - return { - opStackHook: opStackHook, - }; - } - - async deployIsmContracts( - chain: ChainName, - config: NoMetadataIsmConfig, - ): Promise> { - this.logger(`Deploying OpStackIsm to ${chain}`); - const opStackIsmFactory = new OPStackIsm__factory(); - const opStackIsm = await this.multiProvider.handleDeploy( - chain, - opStackIsmFactory, - [config.nativeBridge], - ); - this.logger(`OpStackIsm successfully deployed on ${chain}`); - return { - opStackIsm: opStackIsm, - }; - } - - async postDeploy(chain: string, config: NoMetadataIsmConfig): Promise { - this.logger(`Setting authorized hook for ISM on ${chain}`); - const hookAddress = ( - this.deployedContracts[ - config.origin - ] as HyperlaneContracts - ).opStackHook.address; - const ism = ( - this.deployedContracts[chain] as HyperlaneContracts - ).opStackIsm; - - await this.multiProvider.handleTx( - chain, - ism.setAuthorizedHook(hookAddress), - ); - this.logger(`Authorized hook set successfully to ${hookAddress}`); - } -} diff --git a/typescript/sdk/src/hook/config.ts b/typescript/sdk/src/hook/config.ts deleted file mode 100644 index f8e7de3a9e..0000000000 --- a/typescript/sdk/src/hook/config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { - HookContractType, - InterceptorConfig, - PostDispatchHookConfig, -} from './types'; - -// TODO: what is a hook config was an address? -export const isHookConfig = ( - config: InterceptorConfig, -): config is PostDispatchHookConfig => - typeof config !== 'string' && config.type === HookContractType.HOOK; diff --git a/typescript/sdk/src/hook/contracts/merkleRoot.ts b/typescript/sdk/src/hook/contracts.ts similarity index 55% rename from typescript/sdk/src/hook/contracts/merkleRoot.ts rename to typescript/sdk/src/hook/contracts.ts index ea0280c486..e8dd6f8d90 100644 --- a/typescript/sdk/src/hook/contracts/merkleRoot.ts +++ b/typescript/sdk/src/hook/contracts.ts @@ -4,7 +4,7 @@ import { } from '@hyperlane-xyz/core'; export const merkleRootHookFactories = { - merkleRootHook: new MerkleTreeHook__factory(), + hook: new MerkleTreeHook__factory(), }; export type MerkleRootHookFactories = typeof merkleRootHookFactories; @@ -14,6 +14,10 @@ export const merkleRootIsmFactories = { ism: new StaticMerkleRootMultisigIsm__factory(), }; -export type MerkleRootInterceptorFactories = - | MerkleRootHookFactories - | MerkleRootIsmFactories; +export type MerkleRootInterceptorFactories = MerkleRootHookFactories & + MerkleRootIsmFactories; + +export type HookFactories = MerkleRootHookFactories; +export type IsmFactories = MerkleRootIsmFactories; + +export type InterceptorFactories = HookFactories & IsmFactories; diff --git a/typescript/sdk/src/hook/contracts/opStack.ts b/typescript/sdk/src/hook/contracts/opStack.ts deleted file mode 100644 index 69f70f5986..0000000000 --- a/typescript/sdk/src/hook/contracts/opStack.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { OPStackHook__factory, OPStackIsm__factory } from '@hyperlane-xyz/core'; - -export const opStackHookFactories = { - opStackHook: new OPStackHook__factory(), -}; -export type OpStackHookFactories = typeof opStackHookFactories; - -export const opStackIsmFactories = { - opStackIsm: new OPStackIsm__factory(), -}; - -export type OpStackIsmFactories = typeof opStackIsmFactories; - -export type OpStackInterceptorFactories = - | OpStackHookFactories - | OpStackIsmFactories; diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index c0ec148da9..88bd0f3d7a 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -2,43 +2,42 @@ import { BigNumber } from 'ethers'; import type { Address } from '@hyperlane-xyz/utils'; -import type { IsmConfig, MultisigIsmConfig } from '../ism/types'; +import type { MultisigIsmConfig } from '../ism/types'; import { ChainName } from '../types'; -export enum HookContractType { +export enum InterceptorType { HOOK = 'hook', ISM = 'ism', } export type OpStackHookConfig = { - type: HookContractType.HOOK; + type: InterceptorType.HOOK; nativeBridge: Address; remoteIsm?: Address; destinationDomain: BigNumber; destination: ChainName; }; -export type MerkleTreeHookConfig = { - type: HookContractType.HOOK; +export type MerkleRootHookConfig = { + type: InterceptorType.HOOK; }; -export type MerkleRootInterceptorConfig = - | MerkleTreeHookConfig - | MultisigIsmConfig; +export type MerkleRootInterceptorConfig = { + hook: MerkleRootHookConfig; + ism: MultisigIsmConfig; +}; -export type OpStackInterceptorConfig = OpStackHookConfig | NoMetadataIsmConfig; +export type OpStackInterceptorConfig = { + hook: OpStackHookConfig; + ism: NoMetadataIsmConfig; +}; -export type PostDispatchHookConfig = - | OpStackHookConfig - | MerkleRootInterceptorConfig; +export type HookConfig = OpStackHookConfig | MerkleRootHookConfig; export type NoMetadataIsmConfig = { - type: HookContractType.ISM; + type: InterceptorType.ISM; origin: ChainName; nativeBridge: Address; }; -export type InterceptorConfig = - | PostDispatchHookConfig - | IsmConfig - | NoMetadataIsmConfig; +export type InterceptorConfig = MerkleRootInterceptorConfig; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 8b38768d70..83d8b1b983 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -108,16 +108,14 @@ export { IgpViolationType, OverheadIgpConfig, } from './gas/types'; -export { HyperlaneInterceptorDeployer } from './hook/HyperlaneInterceptorDeployer'; export { MerkleRootInterceptorDeployer } from './hook/MerkleRootInterceptorDeployer'; -export { OpStackInterceptorDeployer } from './hook/OpStackInterceptorDeployer'; export { - HookContractType, + HookConfig, InterceptorConfig, - MerkleTreeHookConfig, + InterceptorType, + MerkleRootHookConfig, NoMetadataIsmConfig, OpStackHookConfig, - PostDispatchHookConfig, } from './hook/types'; export { HyperlaneIsmFactory, diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index 061455700c..b7fd77eedd 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -133,6 +133,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { const multisigIsmFactory = this.getContracts(chain).merkleRootMultisigIsmFactory; + console.log('reachs factory'); const address = await this.deployMOfNFactory( chain, multisigIsmFactory, @@ -219,7 +220,6 @@ export class HyperlaneIsmFactory extends HyperlaneApp { const address = await factory.getAddress(sorted, threshold); const provider = this.multiProvider.getProvider(chain); const code = await provider.getCode(address); - if (code === '0x') { this.logger( `Deploying new ${threshold} of ${values.length} address set to ${chain}`, @@ -345,6 +345,7 @@ export async function moduleCanCertainlyVerify( } } } + return false; } export async function moduleMatchesConfig( diff --git a/typescript/sdk/src/ism/types.ts b/typescript/sdk/src/ism/types.ts index 931041aeb4..0047074dfa 100644 --- a/typescript/sdk/src/ism/types.ts +++ b/typescript/sdk/src/ism/types.ts @@ -6,6 +6,7 @@ import { } from '@hyperlane-xyz/core'; import type { Address } from '@hyperlane-xyz/utils'; +import { NoMetadataIsmConfig } from '../hook/types'; import { ChainMap } from '../types'; export type DeployedIsm = @@ -49,4 +50,5 @@ export type IsmConfig = | Address | RoutingIsmConfig | MultisigIsmConfig - | AggregationIsmConfig; + | AggregationIsmConfig + | NoMetadataIsmConfig; From 8804d9590a3dbf5bb9a4cea029ee7734ed88b93b Mon Sep 17 00:00:00 2001 From: -f Date: Thu, 28 Sep 2023 11:09:25 -0400 Subject: [PATCH 06/18] update validatorKey test fix --- typescript/infra/config/environments/test/multisigIsm.ts | 2 +- typescript/infra/scripts/deploy.ts | 3 --- typescript/sdk/src/ism/HyperlaneIsmFactory.ts | 3 +-- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/typescript/infra/config/environments/test/multisigIsm.ts b/typescript/infra/config/environments/test/multisigIsm.ts index 8709748cc0..402ffad365 100644 --- a/typescript/infra/config/environments/test/multisigIsm.ts +++ b/typescript/infra/config/environments/test/multisigIsm.ts @@ -11,7 +11,7 @@ export const chainToValidator: Record = { export const merkleRootMultisig = (validatorKey: string): MultisigIsmConfig => { return { type: ModuleType.MERKLE_ROOT_MULTISIG, - validators: [validatorKey], + validators: [chainToValidator[validatorKey]], threshold: 1, }; }; diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index 009df47f30..6ea767ed62 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -66,7 +66,6 @@ async function main() { config = objMap(envConfig.core, (_chain) => true); deployer = new HyperlaneIsmFactoryDeployer(multiProvider); } else if (module === Modules.CORE) { - console.log(envConfig); config = envConfig.core; const ismFactory = HyperlaneIsmFactory.fromAddressesMap( getAddresses(environment, Modules.ISM_FACTORY), @@ -74,12 +73,10 @@ async function main() { ); deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory); } else if (module === Modules.HOOK) { - // throw new Error('Hook deployment unimplemented'); if (!envConfig.hooks) { throw new Error(`No hook config for ${environment}`); } config = envConfig.hooks; - console.log(config); const ismFactory = HyperlaneIsmFactory.fromAddressesMap( getAddresses(environment, Modules.ISM_FACTORY), multiProvider, diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index b7fd77eedd..2d210d3f67 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -132,8 +132,6 @@ export class HyperlaneIsmFactory extends HyperlaneApp { const signer = this.multiProvider.getSigner(chain); const multisigIsmFactory = this.getContracts(chain).merkleRootMultisigIsmFactory; - - console.log('reachs factory'); const address = await this.deployMOfNFactory( chain, multisigIsmFactory, @@ -217,6 +215,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { threshold: number, ): Promise
{ const sorted = [...values].sort(); + const address = await factory.getAddress(sorted, threshold); const provider = this.multiProvider.getProvider(chain); const code = await provider.getCode(address); From 191da20153c5fe1bf23603a0b7d1021ffb75d5c0 Mon Sep 17 00:00:00 2001 From: -f Date: Thu, 28 Sep 2023 11:46:57 -0400 Subject: [PATCH 07/18] add to e2e --- rust/utils/run-locally/src/ethereum.rs | 3 +++ .../infra/config/environments/test/multisigIsm.ts | 9 +++++---- typescript/infra/config/multisigIsm.ts | 11 ----------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/rust/utils/run-locally/src/ethereum.rs b/rust/utils/run-locally/src/ethereum.rs index 2119ae5501..7a71264090 100644 --- a/rust/utils/run-locally/src/ethereum.rs +++ b/rust/utils/run-locally/src/ethereum.rs @@ -48,6 +48,9 @@ pub fn start_anvil(config: Arc) -> AgentHandles { log!("Deploying hyperlane core contracts..."); yarn_infra.clone().cmd("deploy-core").run().join(); + log!("Deploying hyperlane hook contracts..."); + yarn_infra.clone().cmd("deploy-hook").run().join(); + log!("Deploying hyperlane igp contracts..."); yarn_infra.cmd("deploy-igp").run().join(); diff --git a/typescript/infra/config/environments/test/multisigIsm.ts b/typescript/infra/config/environments/test/multisigIsm.ts index 402ffad365..bda1c9aa2a 100644 --- a/typescript/infra/config/environments/test/multisigIsm.ts +++ b/typescript/infra/config/environments/test/multisigIsm.ts @@ -1,4 +1,5 @@ import { ChainMap, ModuleType, MultisigIsmConfig } from '@hyperlane-xyz/sdk'; +import { ChainName } from '@hyperlane-xyz/sdk/src'; // the addresses here must line up with the e2e test's validator addresses // Validators are anvil accounts 4-6 @@ -8,18 +9,18 @@ export const chainToValidator: Record = { test3: '0x976EA74026E726554dB657fA54763abd0C3a0aa9', }; -export const merkleRootMultisig = (validatorKey: string): MultisigIsmConfig => { +export const merkleRootMultisig = (chain: ChainName): MultisigIsmConfig => { return { type: ModuleType.MERKLE_ROOT_MULTISIG, - validators: [chainToValidator[validatorKey]], + validators: [chainToValidator[chain]], threshold: 1, }; }; -export const messageIdMultisig = (validatorKey: string): MultisigIsmConfig => { +export const messageIdMultisig = (chain: ChainName): MultisigIsmConfig => { return { type: ModuleType.MESSAGE_ID_MULTISIG, - validators: [validatorKey], + validators: [chainToValidator[chain]], threshold: 1, }; }; diff --git a/typescript/infra/config/multisigIsm.ts b/typescript/infra/config/multisigIsm.ts index 18d1b40f23..232c1f32fe 100644 --- a/typescript/infra/config/multisigIsm.ts +++ b/typescript/infra/config/multisigIsm.ts @@ -20,17 +20,6 @@ const chains = { test: testChains, }; -export const multisigIsm = ( - env: DeployEnvironment, - chain: ChainName, - type: MultisigIsmConfig['type'], - context: Contexts, -): MultisigIsmConfig => { - return context === Contexts.ReleaseCandidate - ? { ...rcMultisigIsmConfigs[chain], type } - : { ...defaultMultisigIsmConfigs[chain], type }; -}; - export const multisigIsms = ( env: DeployEnvironment, local: ChainName, From 19faea75dada64c7db4cd71ad218d0e9e591d7e3 Mon Sep 17 00:00:00 2001 From: -f Date: Thu, 28 Sep 2023 15:53:47 -0400 Subject: [PATCH 08/18] chainmap mailboxes --- .../infra/config/environments/test/interceptor.ts | 4 ++-- .../infra/config/environments/test/multisigIsm.ts | 4 ++-- typescript/infra/package.json | 2 +- typescript/infra/scripts/deploy.ts | 11 ++++++++--- .../sdk/src/hook/MerkleRootInterceptorDeployer.ts | 6 +++--- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/typescript/infra/config/environments/test/interceptor.ts b/typescript/infra/config/environments/test/interceptor.ts index d2da41cf59..e2b9db88a5 100644 --- a/typescript/infra/config/environments/test/interceptor.ts +++ b/typescript/infra/config/environments/test/interceptor.ts @@ -5,7 +5,7 @@ import { } from '@hyperlane-xyz/sdk'; import { objMap } from '@hyperlane-xyz/utils'; -import { merkleRootMultisig } from './multisigIsm'; +import { chainToValidator, merkleRootMultisig } from './multisigIsm'; import { owners } from './owners'; export const merkleRoot: ChainMap = objMap( @@ -15,7 +15,7 @@ export const merkleRoot: ChainMap = objMap( hook: { type: InterceptorType.HOOK, }, - ism: merkleRootMultisig(chain), + ism: merkleRootMultisig(chainToValidator[chain]), }; return config; }, diff --git a/typescript/infra/config/environments/test/multisigIsm.ts b/typescript/infra/config/environments/test/multisigIsm.ts index bda1c9aa2a..104602abae 100644 --- a/typescript/infra/config/environments/test/multisigIsm.ts +++ b/typescript/infra/config/environments/test/multisigIsm.ts @@ -12,7 +12,7 @@ export const chainToValidator: Record = { export const merkleRootMultisig = (chain: ChainName): MultisigIsmConfig => { return { type: ModuleType.MERKLE_ROOT_MULTISIG, - validators: [chainToValidator[chain]], + validators: [chain], threshold: 1, }; }; @@ -20,7 +20,7 @@ export const merkleRootMultisig = (chain: ChainName): MultisigIsmConfig => { export const messageIdMultisig = (chain: ChainName): MultisigIsmConfig => { return { type: ModuleType.MESSAGE_ID_MULTISIG, - validators: [chainToValidator[chain]], + validators: [chain], threshold: 1, }; }; diff --git a/typescript/infra/package.json b/typescript/infra/package.json index 1c3de0237a..aa9fb1b57a 100644 --- a/typescript/infra/package.json +++ b/typescript/infra/package.json @@ -58,7 +58,7 @@ "deploy-igp": "ts-node scripts/deploy.ts -e test -m igp", "deploy-ism": "ts-node scripts/deploy.ts -e test -m ism", "deploy-helloworld": "ts-node scripts/deploy.ts -e test -m helloworld", - "deploy-hook": "ts-node scripts/deploy.ts -e testnet3 -m hook", + "deploy-hook": "ts-node scripts/deploy.ts -e test -m hook", "build": "tsc", "clean": "rm -rf ./dist ./cache", "check": "tsc --noEmit", diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index 3d59669e0c..3e1b17b832 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -13,7 +13,7 @@ import { LiquidityLayerDeployer, MerkleRootInterceptorDeployer, } from '@hyperlane-xyz/sdk'; -import { objMap } from '@hyperlane-xyz/utils'; +import { Address, objMap } from '@hyperlane-xyz/utils'; import { Contexts } from '../config/contexts'; import { deployEnvToSdkEnv } from '../src/config/environment'; @@ -67,7 +67,7 @@ async function main() { } else if (module === Modules.CORE) { config = envConfig.core; const ismFactory = HyperlaneIsmFactory.fromAddressesMap( - getAddresses(environment, Modules.ISM_FACTORY), + getAddresses(environment, Modules.ISM_FACTORY)[environment], multiProvider, ); deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory); @@ -80,10 +80,15 @@ async function main() { getAddresses(environment, Modules.ISM_FACTORY), multiProvider, ); + const mailboxes: ChainMap
= {}; + for (const chain in getAddresses(environment, Modules.CORE)) { + mailboxes[chain] = getAddresses(environment, Modules.CORE)[chain].mailbox; + } + deployer = new MerkleRootInterceptorDeployer( multiProvider, ismFactory, - '0xb7f8bc63bbcad18155201308c8f3540b07f84f5e', + mailboxes, ); } else if (module === Modules.INTERCHAIN_GAS_PAYMASTER) { config = envConfig.igp; diff --git a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts index 68bf2844a8..0e85345a2d 100644 --- a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts +++ b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts @@ -8,7 +8,7 @@ import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; import { MultisigIsmConfig } from '../ism/types'; import { MultiProvider } from '../providers/MultiProvider'; -import { ChainName } from '../types'; +import { ChainMap, ChainName } from '../types'; import { MerkleRootHookFactories, @@ -26,7 +26,7 @@ export class MerkleRootInterceptorDeployer extends HyperlaneDeployer< constructor( multiProvider: MultiProvider, readonly ismFactory: HyperlaneIsmFactory, - readonly mailbox: Address, + readonly mailboxes: ChainMap
, ) { super( multiProvider, @@ -58,7 +58,7 @@ export class MerkleRootInterceptorDeployer extends HyperlaneDeployer< const merkleTreeHook = await this.multiProvider.handleDeploy( chain, merkleTreeFactory, - [this.mailbox], + [this.mailboxes[chain]], ); this.logger(`MerkleRootHook successfully deployed on ${chain}`); return { From 5455b141b2b319f45c470c01e4986d34f195aab5 Mon Sep 17 00:00:00 2001 From: -f Date: Fri, 29 Sep 2023 11:50:57 -0400 Subject: [PATCH 09/18] fix core deploy errpr --- typescript/infra/scripts/deploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index 3e1b17b832..2de5197a3e 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -67,7 +67,7 @@ async function main() { } else if (module === Modules.CORE) { config = envConfig.core; const ismFactory = HyperlaneIsmFactory.fromAddressesMap( - getAddresses(environment, Modules.ISM_FACTORY)[environment], + getAddresses(environment, Modules.ISM_FACTORY), multiProvider, ); deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory); From 23567f8d918eefd6f36373ab8c8e6e2ed231f83d Mon Sep 17 00:00:00 2001 From: -f Date: Fri, 29 Sep 2023 11:52:29 -0400 Subject: [PATCH 10/18] revert multisig changes --- typescript/infra/config/environments/test/multisigIsm.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/typescript/infra/config/environments/test/multisigIsm.ts b/typescript/infra/config/environments/test/multisigIsm.ts index 104602abae..8709748cc0 100644 --- a/typescript/infra/config/environments/test/multisigIsm.ts +++ b/typescript/infra/config/environments/test/multisigIsm.ts @@ -1,5 +1,4 @@ import { ChainMap, ModuleType, MultisigIsmConfig } from '@hyperlane-xyz/sdk'; -import { ChainName } from '@hyperlane-xyz/sdk/src'; // the addresses here must line up with the e2e test's validator addresses // Validators are anvil accounts 4-6 @@ -9,18 +8,18 @@ export const chainToValidator: Record = { test3: '0x976EA74026E726554dB657fA54763abd0C3a0aa9', }; -export const merkleRootMultisig = (chain: ChainName): MultisigIsmConfig => { +export const merkleRootMultisig = (validatorKey: string): MultisigIsmConfig => { return { type: ModuleType.MERKLE_ROOT_MULTISIG, - validators: [chain], + validators: [validatorKey], threshold: 1, }; }; -export const messageIdMultisig = (chain: ChainName): MultisigIsmConfig => { +export const messageIdMultisig = (validatorKey: string): MultisigIsmConfig => { return { type: ModuleType.MESSAGE_ID_MULTISIG, - validators: [chain], + validators: [validatorKey], threshold: 1, }; }; From f5161848cfa0a4c11fd586a59592c637c76b0ebb Mon Sep 17 00:00:00 2001 From: -f Date: Fri, 29 Sep 2023 14:15:49 -0400 Subject: [PATCH 11/18] handleDeploy -> deployContract --- .../sdk/src/hook/MerkleRootInterceptorDeployer.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts index 0e85345a2d..03ea7d2017 100644 --- a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts +++ b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts @@ -1,6 +1,5 @@ import debug from 'debug'; -import { MerkleTreeHook__factory } from '@hyperlane-xyz/core'; import { Address } from '@hyperlane-xyz/utils'; import { HyperlaneContracts } from '../contracts/types'; @@ -54,13 +53,9 @@ export class MerkleRootInterceptorDeployer extends HyperlaneDeployer< _: MerkleRootHookConfig, ): Promise> { this.logger(`Deploying MerkleRootHook to ${chain}`); - const merkleTreeFactory = new MerkleTreeHook__factory(); - const merkleTreeHook = await this.multiProvider.handleDeploy( - chain, - merkleTreeFactory, - [this.mailboxes[chain]], - ); - this.logger(`MerkleRootHook successfully deployed on ${chain}`); + const merkleTreeHook = await this.deployContract(chain, 'hook', [ + this.mailboxes[chain], + ]); return { hook: merkleTreeHook, }; @@ -70,11 +65,11 @@ export class MerkleRootInterceptorDeployer extends HyperlaneDeployer< chain: ChainName, config: MultisigIsmConfig, ): Promise> { + this.logger(`Deploying MerkleRootMultisigIsm to ${chain}`); const ism = await this.ismFactory.deployMerkleRootMultisigIsm( chain, config, ); - return { ism: ism, }; From 2822ccb5b33b12bd19deb67a4d14278b1b9ec51a Mon Sep 17 00:00:00 2001 From: -f Date: Fri, 29 Sep 2023 15:54:06 -0400 Subject: [PATCH 12/18] cleanup hook->interceptor --- .../config/environments/mainnet2/hooks.ts | 36 ------------------- .../config/environments/mainnet2/index.ts | 2 -- .../infra/config/environments/test/index.ts | 3 +- .../config/environments/test/interceptor.ts | 14 -------- .../config/environments/testnet3/hooks.ts | 34 ------------------ .../config/environments/testnet3/index.ts | 2 -- typescript/infra/scripts/deploy.ts | 4 +-- typescript/infra/scripts/utils.ts | 22 ------------ typescript/infra/src/config/environment.ts | 2 +- typescript/sdk/src/hook/types.ts | 4 +-- typescript/sdk/src/index.ts | 2 +- typescript/sdk/src/ism/types.ts | 4 +-- 12 files changed, 9 insertions(+), 120 deletions(-) delete mode 100644 typescript/infra/config/environments/mainnet2/hooks.ts delete mode 100644 typescript/infra/config/environments/testnet3/hooks.ts diff --git a/typescript/infra/config/environments/mainnet2/hooks.ts b/typescript/infra/config/environments/mainnet2/hooks.ts deleted file mode 100644 index 20e334f8d6..0000000000 --- a/typescript/infra/config/environments/mainnet2/hooks.ts +++ /dev/null @@ -1,36 +0,0 @@ -// import { -// ChainMap, -// InterceptorType, -// InterceptorConfig, -// NoMetadataIsmConfig, -// OpStackHookConfig, -// filterByChains, -// } from '@hyperlane-xyz/sdk'; -// import { objMap } from '@hyperlane-xyz/utils'; - -// import { owners } from './owners'; - -// const chainNameFilter = new Set(['ethereum', 'optimism']); -// const filteredOwnersResult = filterByChains(owners, chainNameFilter); - -// export const hooks: ChainMap = objMap( -// filteredOwnersResult, -// (chain) => { -// if (chain === 'ethereum') { -// const hookConfig: OpStackHookConfig = { -// InterceptorType: InterceptorType.HOOK, -// mailbox: '0x23', -// nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1', -// remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first -// destination: 'optimism', -// }; -// return hookConfig; -// } else { -// const ismConfig: NoMetadataIsmConfig = { -// InterceptorType: InterceptorType.ISM, -// nativeBridge: '0x4200000000000000000000000000000000000007', -// }; -// return ismConfig; -// } -// }, -// ); diff --git a/typescript/infra/config/environments/mainnet2/index.ts b/typescript/infra/config/environments/mainnet2/index.ts index 17b2839309..a204eba239 100644 --- a/typescript/infra/config/environments/mainnet2/index.ts +++ b/typescript/infra/config/environments/mainnet2/index.ts @@ -14,7 +14,6 @@ import { core } from './core'; import { keyFunderConfig } from './funding'; import { storageGasOracleConfig } from './gas-oracle'; import { helloWorld } from './helloworld'; -// import { hooks } from './hooks'; import { igp } from './igp'; import { infrastructure } from './infrastructure'; import { bridgeAdapterConfigs, relayerConfig } from './liquidityLayer'; @@ -45,7 +44,6 @@ export const environment: EnvironmentConfig = { igp, owners, infra: infrastructure, - // hooks, helloWorld, keyFunderConfig, storageGasOracleConfig, diff --git a/typescript/infra/config/environments/test/index.ts b/typescript/infra/config/environments/test/index.ts index bd776d8308..1bd489d11b 100644 --- a/typescript/infra/config/environments/test/index.ts +++ b/typescript/infra/config/environments/test/index.ts @@ -8,7 +8,6 @@ import { agents } from './agent'; import { testConfigs } from './chains'; import { core } from './core'; import { storageGasOracleConfig } from './gas-oracle'; -// import { hooks } from './hooks'; import { igp } from './igp'; import { infra } from './infra'; import { merkleRoot } from './interceptor'; @@ -19,7 +18,7 @@ export const environment: EnvironmentConfig = { chainMetadataConfigs: testConfigs, agents, core, - hooks: merkleRoot, + interceptor: merkleRoot, igp, owners, infra, diff --git a/typescript/infra/config/environments/test/interceptor.ts b/typescript/infra/config/environments/test/interceptor.ts index e2b9db88a5..2ab61d93fc 100644 --- a/typescript/infra/config/environments/test/interceptor.ts +++ b/typescript/infra/config/environments/test/interceptor.ts @@ -20,17 +20,3 @@ export const merkleRoot: ChainMap = objMap( return config; }, ); - -// const mrConfig: ChainMap = { -// test1: { -// type: InterceptorType.HOOK, -// destinationDomain: BigNumber.from(10), -// destination: 'test2', -// nativeBridge: '0xa85233c63b9ee964add6f2cffe00fd84eb32338f', -// }, -// test2: { -// type: InterceptorType.ISM, -// origin: 'test1', -// nativeBridge: '0x322813fd9a801c5507c9de605d63cea4f2ce6c44', -// }, -// }; diff --git a/typescript/infra/config/environments/testnet3/hooks.ts b/typescript/infra/config/environments/testnet3/hooks.ts deleted file mode 100644 index 2f616c68b6..0000000000 --- a/typescript/infra/config/environments/testnet3/hooks.ts +++ /dev/null @@ -1,34 +0,0 @@ -// import { -// ChainMap, -// HookContractType, -// InterceptorConfig, -// NoMetadataIsmConfig, -// OpStackHookConfig, -// filterByChains, -// } from '@hyperlane-xyz/sdk'; -// import { objMap } from '@hyperlane-xyz/utils'; - -// import { owners } from './owners'; - -// const chainNameFilter = new Set(['goerli', 'optimismgoerli']); -// const filteredOwnersResult = filterByChains(owners, chainNameFilter); - -// export const hooks: ChainMap = objMap( -// filteredOwnersResult, -// (chain) => { -// if (chain === 'goerli') { -// const hookConfig: OpStackHookConfig = { -// hookContractType: HookContractType.HOOK, -// nativeBridge: '0x5086d1eEF304eb5284A0f6720f79403b4e9bE294', -// destination: 'optimismgoerli', -// }; -// return hookConfig; -// } else { -// const ismConfig: NoMetadataIsmConfig = { -// hookContractType: HookContractType.ISM, -// nativeBridge: '0x4200000000000000000000000000000000000007', -// }; -// return ismConfig; -// } -// }, -// ); diff --git a/typescript/infra/config/environments/testnet3/index.ts b/typescript/infra/config/environments/testnet3/index.ts index 9bb2134b6c..a402010b3b 100644 --- a/typescript/infra/config/environments/testnet3/index.ts +++ b/typescript/infra/config/environments/testnet3/index.ts @@ -14,7 +14,6 @@ import { core } from './core'; import { keyFunderConfig } from './funding'; import { storageGasOracleConfig } from './gas-oracle'; import { helloWorld } from './helloworld'; -// import { hooks } from './hooks'; import { igp } from './igp'; import { infrastructure } from './infrastructure'; import { bridgeAdapterConfigs } from './liquidityLayer'; @@ -46,7 +45,6 @@ export const environment: EnvironmentConfig = { igp, infra: infrastructure, helloWorld, - // hooks, owners, keyFunderConfig, liquidityLayerConfig: { diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index 2de5197a3e..3c70022603 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -72,10 +72,10 @@ async function main() { ); deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory); } else if (module === Modules.HOOK) { - if (!envConfig.hooks) { + if (!envConfig.interceptor) { throw new Error(`No hook config for ${environment}`); } - config = envConfig.hooks; + config = envConfig.interceptor; const ismFactory = HyperlaneIsmFactory.fromAddressesMap( getAddresses(environment, Modules.ISM_FACTORY), multiProvider, diff --git a/typescript/infra/scripts/utils.ts b/typescript/infra/scripts/utils.ts index 136324e0cb..c2cbf41e8b 100644 --- a/typescript/infra/scripts/utils.ts +++ b/typescript/infra/scripts/utils.ts @@ -39,7 +39,6 @@ import { import { fetchProvider } from '../src/config/chain'; import { EnvironmentNames, deployEnvToSdkEnv } from '../src/config/environment'; import { Role } from '../src/roles'; -import { impersonateAccount, useLocalProvider } from '../src/utils/fork'; import { assertContext, assertRole, readJSON } from '../src/utils/utils'; export enum Modules { @@ -380,24 +379,3 @@ export function getValidatorsByChain( } return validators; } - -export async function getHooksProvider( - multiProvider: MultiProvider, - environment: DeployEnvironment, -): Promise { - const hooksProvider = new MultiProvider(); - const hooksConfig = getEnvironmentConfig(environment).hooks; - if (!hooksConfig) { - return hooksProvider; - } - for (const chain of Object.keys(hooksConfig)) { - // need to use different url for two forks simultaneously - // need another rpc param - await useLocalProvider(multiProvider, chain); - } - const signer = await impersonateAccount( - '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', - ); - hooksProvider.setSharedSigner(signer); - return hooksProvider; -} diff --git a/typescript/infra/src/config/environment.ts b/typescript/infra/src/config/environment.ts index f3e8f401be..1b580d2110 100644 --- a/typescript/infra/src/config/environment.ts +++ b/typescript/infra/src/config/environment.ts @@ -37,7 +37,7 @@ export type EnvironmentConfig = { // Each AgentConfig, keyed by the context agents: Partial>; core: ChainMap; - hooks?: ChainMap; + interceptor?: ChainMap; igp: ChainMap; owners: ChainMap
; infra: InfrastructureConfig; diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index 88bd0f3d7a..ed838980d7 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -29,12 +29,12 @@ export type MerkleRootInterceptorConfig = { export type OpStackInterceptorConfig = { hook: OpStackHookConfig; - ism: NoMetadataIsmConfig; + ism: OPStackIsmConfig; }; export type HookConfig = OpStackHookConfig | MerkleRootHookConfig; -export type NoMetadataIsmConfig = { +export type OPStackIsmConfig = { type: InterceptorType.ISM; origin: ChainName; nativeBridge: Address; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 48e92c22d7..c44229a666 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -114,7 +114,7 @@ export { InterceptorConfig, InterceptorType, MerkleRootHookConfig, - NoMetadataIsmConfig, + OPStackIsmConfig, OpStackHookConfig, } from './hook/types'; export { diff --git a/typescript/sdk/src/ism/types.ts b/typescript/sdk/src/ism/types.ts index 0047074dfa..d3f0388015 100644 --- a/typescript/sdk/src/ism/types.ts +++ b/typescript/sdk/src/ism/types.ts @@ -6,7 +6,7 @@ import { } from '@hyperlane-xyz/core'; import type { Address } from '@hyperlane-xyz/utils'; -import { NoMetadataIsmConfig } from '../hook/types'; +import { OPStackIsmConfig } from '../hook/types'; import { ChainMap } from '../types'; export type DeployedIsm = @@ -51,4 +51,4 @@ export type IsmConfig = | RoutingIsmConfig | MultisigIsmConfig | AggregationIsmConfig - | NoMetadataIsmConfig; + | OPStackIsmConfig; From abfeb0bc2885428ebbefa1063e01b08e9996393b Mon Sep 17 00:00:00 2001 From: -f Date: Mon, 2 Oct 2023 13:24:55 -0400 Subject: [PATCH 13/18] messageId deployer as well --- .../config/environments/test/interceptor.ts | 20 ++++++----- .../config/environments/test/multisigIsm.ts | 6 ++-- .../src/hook/MerkleRootInterceptorDeployer.ts | 34 +++++++++++++------ typescript/sdk/src/hook/contracts.ts | 13 +++++-- typescript/sdk/src/hook/types.ts | 33 +++--------------- typescript/sdk/src/index.ts | 4 +-- typescript/sdk/src/ism/HyperlaneIsmFactory.ts | 20 ----------- typescript/sdk/src/ism/types.ts | 13 +++---- 8 files changed, 60 insertions(+), 83 deletions(-) diff --git a/typescript/infra/config/environments/test/interceptor.ts b/typescript/infra/config/environments/test/interceptor.ts index 2ab61d93fc..133a629c3f 100644 --- a/typescript/infra/config/environments/test/interceptor.ts +++ b/typescript/infra/config/environments/test/interceptor.ts @@ -1,11 +1,12 @@ -import { - ChainMap, - InterceptorConfig, - InterceptorType, -} from '@hyperlane-xyz/sdk'; +import { ChainMap, InterceptorConfig } from '@hyperlane-xyz/sdk'; +import { HookType } from '@hyperlane-xyz/sdk/src/hook/types'; import { objMap } from '@hyperlane-xyz/utils'; -import { chainToValidator, merkleRootMultisig } from './multisigIsm'; +import { + chainToValidator, + merkleRootMultisig, + messageIdMultisig, +} from './multisigIsm'; import { owners } from './owners'; export const merkleRoot: ChainMap = objMap( @@ -13,9 +14,12 @@ export const merkleRoot: ChainMap = objMap( (chain, _) => { const config: InterceptorConfig = { hook: { - type: InterceptorType.HOOK, + type: HookType.MERKLE_ROOT_HOOK, }, - ism: merkleRootMultisig(chainToValidator[chain]), + ism: + Math.random() < 0.5 + ? merkleRootMultisig(chainToValidator[chain]) + : messageIdMultisig(chainToValidator[chain]), }; return config; }, diff --git a/typescript/infra/config/environments/test/multisigIsm.ts b/typescript/infra/config/environments/test/multisigIsm.ts index 8709748cc0..a310d258f7 100644 --- a/typescript/infra/config/environments/test/multisigIsm.ts +++ b/typescript/infra/config/environments/test/multisigIsm.ts @@ -27,7 +27,7 @@ export const messageIdMultisig = (validatorKey: string): MultisigIsmConfig => { // the addresses here must line up with the e2e test's validator addresses export const multisigIsm: ChainMap = { // Validators are anvil accounts 4-6 - test1: messageIdMultisig('test1'), - test2: merkleRootMultisig('test2'), - test3: messageIdMultisig('test3'), + test1: messageIdMultisig(chainToValidator['test1']), + test2: merkleRootMultisig(chainToValidator['test2']), + test3: messageIdMultisig(chainToValidator['test3']), }; diff --git a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts index 03ea7d2017..f4d4b0952b 100644 --- a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts +++ b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts @@ -1,18 +1,22 @@ import debug from 'debug'; +import { + StaticMerkleRootMultisigIsm, + StaticMessageIdMultisigIsm, +} from '@hyperlane-xyz/core'; import { Address } from '@hyperlane-xyz/utils'; import { HyperlaneContracts } from '../contracts/types'; import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; -import { MultisigIsmConfig } from '../ism/types'; +import { ModuleType, MultisigIsmConfig } from '../ism/types'; import { MultiProvider } from '../providers/MultiProvider'; import { ChainMap, ChainName } from '../types'; import { MerkleRootHookFactories, MerkleRootInterceptorFactories, - MerkleRootIsmFactories, + MultisigIsmFactories, merkleRootHookFactories, merkleRootIsmFactories, } from './contracts'; @@ -64,14 +68,22 @@ export class MerkleRootInterceptorDeployer extends HyperlaneDeployer< async deployIsmContracts( chain: ChainName, config: MultisigIsmConfig, - ): Promise> { - this.logger(`Deploying MerkleRootMultisigIsm to ${chain}`); - const ism = await this.ismFactory.deployMerkleRootMultisigIsm( - chain, - config, - ); - return { - ism: ism, - }; + ): Promise> { + const ism = await this.ismFactory.deploy(chain, config); + if (config.type === ModuleType.MERKLE_ROOT_MULTISIG) { + this.logger(`Deploying StaticMerkleRootMultisigIsm to ${chain}`); + return { + ism: ism as StaticMerkleRootMultisigIsm, + }; + } else if (config.type === ModuleType.MESSAGE_ID_MULTISIG) { + this.logger(`Deploying StaticMessageIdMultisigIsm to ${chain}`); + return { + ism: ism as StaticMessageIdMultisigIsm, + }; + } else { + throw new Error( + `Unexpected ISM type ${config.type} for MerkleRootInterceptorDeployer`, + ); + } } } diff --git a/typescript/sdk/src/hook/contracts.ts b/typescript/sdk/src/hook/contracts.ts index e8dd6f8d90..7a32b3e986 100644 --- a/typescript/sdk/src/hook/contracts.ts +++ b/typescript/sdk/src/hook/contracts.ts @@ -1,23 +1,30 @@ import { MerkleTreeHook__factory, StaticMerkleRootMultisigIsm__factory, + StaticMessageIdMultisigIsm__factory, } from '@hyperlane-xyz/core'; export const merkleRootHookFactories = { hook: new MerkleTreeHook__factory(), }; +export const messageIdMultisigIsmFactory = { + ism: new StaticMessageIdMultisigIsm__factory(), +}; + export type MerkleRootHookFactories = typeof merkleRootHookFactories; -export type MerkleRootIsmFactories = typeof merkleRootIsmFactories; +export type MultisigIsmFactories = + | typeof merkleRootIsmFactories + | typeof messageIdMultisigIsmFactory; export const merkleRootIsmFactories = { ism: new StaticMerkleRootMultisigIsm__factory(), }; export type MerkleRootInterceptorFactories = MerkleRootHookFactories & - MerkleRootIsmFactories; + MultisigIsmFactories; export type HookFactories = MerkleRootHookFactories; -export type IsmFactories = MerkleRootIsmFactories; +export type IsmFactories = MultisigIsmFactories; export type InterceptorFactories = HookFactories & IsmFactories; diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index ed838980d7..a14944eb1a 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -1,25 +1,11 @@ -import { BigNumber } from 'ethers'; - -import type { Address } from '@hyperlane-xyz/utils'; - import type { MultisigIsmConfig } from '../ism/types'; -import { ChainName } from '../types'; -export enum InterceptorType { - HOOK = 'hook', - ISM = 'ism', +export enum HookType { + MERKLE_ROOT_HOOK = 'merkleRootHook', } -export type OpStackHookConfig = { - type: InterceptorType.HOOK; - nativeBridge: Address; - remoteIsm?: Address; - destinationDomain: BigNumber; - destination: ChainName; -}; - export type MerkleRootHookConfig = { - type: InterceptorType.HOOK; + type: HookType.MERKLE_ROOT_HOOK; }; export type MerkleRootInterceptorConfig = { @@ -27,17 +13,6 @@ export type MerkleRootInterceptorConfig = { ism: MultisigIsmConfig; }; -export type OpStackInterceptorConfig = { - hook: OpStackHookConfig; - ism: OPStackIsmConfig; -}; - -export type HookConfig = OpStackHookConfig | MerkleRootHookConfig; - -export type OPStackIsmConfig = { - type: InterceptorType.ISM; - origin: ChainName; - nativeBridge: Address; -}; +export type HookConfig = MerkleRootHookConfig; export type InterceptorConfig = MerkleRootInterceptorConfig; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index c44229a666..25dadc56cd 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -111,11 +111,9 @@ export { export { MerkleRootInterceptorDeployer } from './hook/MerkleRootInterceptorDeployer'; export { HookConfig, + HookType, InterceptorConfig, - InterceptorType, MerkleRootHookConfig, - OPStackIsmConfig, - OpStackHookConfig, } from './hook/types'; export { HyperlaneIsmFactory, diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index 2d210d3f67..c187924fdd 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -9,8 +9,6 @@ import { IRoutingIsm__factory, StaticAggregationIsm__factory, StaticMOfNAddressSetFactory, - StaticMerkleRootMultisigIsm, - StaticMerkleRootMultisigIsm__factory, } from '@hyperlane-xyz/core'; import { Address, eqAddress, formatMessage, warn } from '@hyperlane-xyz/utils'; @@ -124,24 +122,6 @@ export class HyperlaneIsmFactory extends HyperlaneApp { return IMultisigIsm__factory.connect(address, signer); } - public async deployMerkleRootMultisigIsm( - chain: ChainName, - config: MultisigIsmConfig, - ): Promise { - this.logger(`Deploying Merkle Root Multisig ISM to ${chain}`); - const signer = this.multiProvider.getSigner(chain); - const multisigIsmFactory = - this.getContracts(chain).merkleRootMultisigIsmFactory; - const address = await this.deployMOfNFactory( - chain, - multisigIsmFactory, - config.validators, - config.threshold, - ); - - return StaticMerkleRootMultisigIsm__factory.connect(address, signer); - } - private async deployRoutingIsm(chain: ChainName, config: RoutingIsmConfig) { const signer = this.multiProvider.getSigner(chain); const routingIsmFactory = this.getContracts(chain).routingIsmFactory; diff --git a/typescript/sdk/src/ism/types.ts b/typescript/sdk/src/ism/types.ts index d3f0388015..23c6bdaca8 100644 --- a/typescript/sdk/src/ism/types.ts +++ b/typescript/sdk/src/ism/types.ts @@ -3,24 +3,26 @@ import { IInterchainSecurityModule, IMultisigIsm, IRoutingIsm, + StaticMerkleRootMultisigIsm, + StaticMessageIdMultisigIsm, } from '@hyperlane-xyz/core'; import type { Address } from '@hyperlane-xyz/utils'; -import { OPStackIsmConfig } from '../hook/types'; import { ChainMap } from '../types'; export type DeployedIsm = | IInterchainSecurityModule | IMultisigIsm | IAggregationIsm - | IRoutingIsm; + | IRoutingIsm + | StaticMessageIdMultisigIsm + | StaticMerkleRootMultisigIsm; export enum ModuleType { UNUSED, ROUTING, AGGREGATION, - // DEPRECATED - LEGACY_MULTISIG, + LEGACY_MULTISIG, // DEPRECATED MERKLE_ROOT_MULTISIG, MESSAGE_ID_MULTISIG, } @@ -50,5 +52,4 @@ export type IsmConfig = | Address | RoutingIsmConfig | MultisigIsmConfig - | AggregationIsmConfig - | OPStackIsmConfig; + | AggregationIsmConfig; From a53dd91d02cc382612463742e19dcb8b278d1a73 Mon Sep 17 00:00:00 2001 From: -f Date: Mon, 2 Oct 2023 16:03:22 -0400 Subject: [PATCH 14/18] only deployer merkleTreeHook --- rust/config/testnet_config.json | 158 +++--------------- .../infra/config/environments/test/hooks.ts | 16 ++ .../infra/config/environments/test/index.ts | 4 +- .../config/environments/test/interceptor.ts | 26 --- typescript/infra/scripts/deploy.ts | 12 +- typescript/infra/src/config/environment.ts | 4 +- .../src/hook/MerkleRootInterceptorDeployer.ts | 89 ---------- typescript/sdk/src/hook/contracts.ts | 33 +--- typescript/sdk/src/hook/types.ts | 17 +- typescript/sdk/src/index.ts | 9 +- 10 files changed, 55 insertions(+), 313 deletions(-) create mode 100644 typescript/infra/config/environments/test/hooks.ts delete mode 100644 typescript/infra/config/environments/test/interceptor.ts delete mode 100644 typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts diff --git a/rust/config/testnet_config.json b/rust/config/testnet_config.json index baf249942c..d5f52a58d9 100644 --- a/rust/config/testnet_config.json +++ b/rust/config/testnet_config.json @@ -1,162 +1,42 @@ { "chains": { - "alfajores": { - "name": "alfajores", - "domain": 44787, + "test1": { + "name": "test1", + "domain": 13371, "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + "mailbox": "0x975Ab64F4901Af5f0C96636deA0b9de3419D0c2F", + "validatorAnnounce": "0x742489F22807ebB4C36ca6cD95c3e1C044B7B6c8" }, "protocol": "ethereum", "finalityBlocks": 0, "index": { - "from": 14863532 + "from": 322 } }, - "fuji": { - "name": "fuji", - "domain": 43113, + "test2": { + "name": "test2", + "domain": 13372, "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" - }, - "protocol": "ethereum", - "finalityBlocks": 3, - "index": { - "from": 16330615 - } - }, - "mumbai": { - "name": "mumbai", - "domain": 80001, - "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" - }, - "protocol": "ethereum", - "finalityBlocks": 32, - "index": { - "from": 29390033 - } - }, - "bsctestnet": { - "name": "bsctestnet", - "domain": 97, - "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" - }, - "protocol": "ethereum", - "finalityBlocks": 9, - "index": { - "from": 25001629 - } - }, - "goerli": { - "name": "goerli", - "domain": 5, - "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" - }, - "protocol": "ethereum", - "finalityBlocks": 2, - "index": { - "from": 8039005 - } - }, - "sepolia": { - "name": "sepolia", - "domain": 11155111, - "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" - }, - "protocol": "ethereum", - "finalityBlocks": 2, - "index": { - "from": 3082913 - } - }, - "moonbasealpha": { - "name": "moonbasealpha", - "domain": 1287, - "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" - }, - "protocol": "ethereum", - "finalityBlocks": 1, - "index": { - "from": 3310405 - } - }, - "optimismgoerli": { - "name": "optimismgoerli", - "domain": 420, - "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + "mailbox": "0x3fdc08D815cc4ED3B7F69Ee246716f2C8bCD6b07", + "validatorAnnounce": "0x2A590C461Db46bca129E8dBe5C3998A8fF402e76" }, "protocol": "ethereum", "finalityBlocks": 1, "index": { - "from": 3055263 + "from": 322 } }, - "arbitrumgoerli": { - "name": "arbitrumgoerli", - "domain": 421613, + "test3": { + "name": "test3", + "domain": 13373, "addresses": { - "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", - "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", - "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + "mailbox": "0x9849832a1d8274aaeDb1112ad9686413461e7101", + "validatorAnnounce": "0x262e2b50219620226C5fB5956432A88fffd94Ba7" }, "protocol": "ethereum", - "finalityBlocks": 1, - "index": { - "from": 1941997 - } - }, - "solanadevnet": { - "name": "solanadevnet", - "domain": 1399811151, - "addresses": { - "mailbox": "4v25Dz9RccqUrTzmfHzJMsjd1iVoNrWzeJ4o6GYuJrVn", - "interchainGasPaymaster": "7hMPEGdgBQFsjEz3aaNwZp8WMFHs615zAM3erXBDJuJR", - "validatorAnnounce": "CMHKvdq4CopDf7qXnDCaTybS15QekQeRt4oUB219yxsp" - }, - "protocol": "sealevel", - "finalityBlocks": 0, - "connection": { - "type": "http", - "url": "https://api.devnet.solana.com" - }, - "index": { - "from": 1, - "mode": "sequence" - } - }, - "proteustestnet": { - "name": "proteustestnet", - "domain": 88002, - "addresses": { - "mailbox": "0x918D3924Fad8F71551D9081172e9Bb169745461e", - "interchainGasPaymaster": "0x06b62A9F5AEcc1E601D0E02732b4E1D0705DE7Db", - "validatorAnnounce": "0xEEea93d0d0287c71e47B3f62AFB0a92b9E8429a1" - }, - "protocol": "ethereum", - "finalityBlocks": 1, + "finalityBlocks": 2, "index": { - "from": 8609588 + "from": 322 } } } diff --git a/typescript/infra/config/environments/test/hooks.ts b/typescript/infra/config/environments/test/hooks.ts new file mode 100644 index 0000000000..df9cffeab4 --- /dev/null +++ b/typescript/infra/config/environments/test/hooks.ts @@ -0,0 +1,16 @@ +import { ChainMap } from '@hyperlane-xyz/sdk'; +import { MerkleTreeHookConfig } from '@hyperlane-xyz/sdk/dist/hook/types'; +import { HookType } from '@hyperlane-xyz/sdk/src/hook/types'; +import { objMap } from '@hyperlane-xyz/utils'; + +import { owners } from './owners'; + +export const merkleTree: ChainMap = objMap( + owners, + (_, __) => { + const config: MerkleTreeHookConfig = { + type: HookType.MERKLE_TREE_HOOK, + }; + return config; + }, +); diff --git a/typescript/infra/config/environments/test/index.ts b/typescript/infra/config/environments/test/index.ts index 1bd489d11b..6004ff82cd 100644 --- a/typescript/infra/config/environments/test/index.ts +++ b/typescript/infra/config/environments/test/index.ts @@ -8,9 +8,9 @@ import { agents } from './agent'; import { testConfigs } from './chains'; import { core } from './core'; import { storageGasOracleConfig } from './gas-oracle'; +import { merkleTree } from './hooks'; import { igp } from './igp'; import { infra } from './infra'; -import { merkleRoot } from './interceptor'; import { owners } from './owners'; export const environment: EnvironmentConfig = { @@ -18,7 +18,7 @@ export const environment: EnvironmentConfig = { chainMetadataConfigs: testConfigs, agents, core, - interceptor: merkleRoot, + hook: merkleTree, igp, owners, infra, diff --git a/typescript/infra/config/environments/test/interceptor.ts b/typescript/infra/config/environments/test/interceptor.ts deleted file mode 100644 index 133a629c3f..0000000000 --- a/typescript/infra/config/environments/test/interceptor.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ChainMap, InterceptorConfig } from '@hyperlane-xyz/sdk'; -import { HookType } from '@hyperlane-xyz/sdk/src/hook/types'; -import { objMap } from '@hyperlane-xyz/utils'; - -import { - chainToValidator, - merkleRootMultisig, - messageIdMultisig, -} from './multisigIsm'; -import { owners } from './owners'; - -export const merkleRoot: ChainMap = objMap( - owners, - (chain, _) => { - const config: InterceptorConfig = { - hook: { - type: HookType.MERKLE_ROOT_HOOK, - }, - ism: - Math.random() < 0.5 - ? merkleRootMultisig(chainToValidator[chain]) - : messageIdMultisig(chainToValidator[chain]), - }; - return config; - }, -); diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index 3c70022603..80eed170b5 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -5,13 +5,13 @@ import { ChainMap, HyperlaneCoreDeployer, HyperlaneDeployer, + HyperlaneHookDeployer, HyperlaneIgpDeployer, HyperlaneIsmFactory, HyperlaneIsmFactoryDeployer, InterchainAccountDeployer, InterchainQueryDeployer, LiquidityLayerDeployer, - MerkleRootInterceptorDeployer, } from '@hyperlane-xyz/sdk'; import { Address, objMap } from '@hyperlane-xyz/utils'; @@ -72,10 +72,10 @@ async function main() { ); deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory); } else if (module === Modules.HOOK) { - if (!envConfig.interceptor) { + if (!envConfig.hook) { throw new Error(`No hook config for ${environment}`); } - config = envConfig.interceptor; + config = envConfig.hook; const ismFactory = HyperlaneIsmFactory.fromAddressesMap( getAddresses(environment, Modules.ISM_FACTORY), multiProvider, @@ -85,11 +85,7 @@ async function main() { mailboxes[chain] = getAddresses(environment, Modules.CORE)[chain].mailbox; } - deployer = new MerkleRootInterceptorDeployer( - multiProvider, - ismFactory, - mailboxes, - ); + deployer = new HyperlaneHookDeployer(multiProvider, ismFactory, mailboxes); } else if (module === Modules.INTERCHAIN_GAS_PAYMASTER) { config = envConfig.igp; deployer = new HyperlaneIgpDeployer(multiProvider); diff --git a/typescript/infra/src/config/environment.ts b/typescript/infra/src/config/environment.ts index 1b580d2110..623bfc88c2 100644 --- a/typescript/infra/src/config/environment.ts +++ b/typescript/infra/src/config/environment.ts @@ -6,7 +6,7 @@ import { ChainName, CoreConfig, HyperlaneEnvironment, - InterceptorConfig, + MerkleTreeHookConfig, MultiProvider, OverheadIgpConfig, } from '@hyperlane-xyz/sdk'; @@ -37,7 +37,7 @@ export type EnvironmentConfig = { // Each AgentConfig, keyed by the context agents: Partial>; core: ChainMap; - interceptor?: ChainMap; + hook?: ChainMap; igp: ChainMap; owners: ChainMap
; infra: InfrastructureConfig; diff --git a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts b/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts deleted file mode 100644 index f4d4b0952b..0000000000 --- a/typescript/sdk/src/hook/MerkleRootInterceptorDeployer.ts +++ /dev/null @@ -1,89 +0,0 @@ -import debug from 'debug'; - -import { - StaticMerkleRootMultisigIsm, - StaticMessageIdMultisigIsm, -} from '@hyperlane-xyz/core'; -import { Address } from '@hyperlane-xyz/utils'; - -import { HyperlaneContracts } from '../contracts/types'; -import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; -import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; -import { ModuleType, MultisigIsmConfig } from '../ism/types'; -import { MultiProvider } from '../providers/MultiProvider'; -import { ChainMap, ChainName } from '../types'; - -import { - MerkleRootHookFactories, - MerkleRootInterceptorFactories, - MultisigIsmFactories, - merkleRootHookFactories, - merkleRootIsmFactories, -} from './contracts'; -import { MerkleRootHookConfig, MerkleRootInterceptorConfig } from './types'; - -export class MerkleRootInterceptorDeployer extends HyperlaneDeployer< - MerkleRootInterceptorConfig, - MerkleRootInterceptorFactories -> { - constructor( - multiProvider: MultiProvider, - readonly ismFactory: HyperlaneIsmFactory, - readonly mailboxes: ChainMap
, - ) { - super( - multiProvider, - { ...merkleRootHookFactories, ...merkleRootIsmFactories }, - { - logger: debug('hyperlane:MerkleRootInterceptorDeployer'), - }, - ); - } - - async deployContracts( - chain: ChainName, - config: MerkleRootInterceptorConfig, - ): Promise> { - const hookContracts = await this.deployHookContracts(chain, config.hook); - const ismContracts = await this.deployIsmContracts(chain, config.ism); - return { - ...hookContracts, - ...ismContracts, - }; - } - - async deployHookContracts( - chain: ChainName, - _: MerkleRootHookConfig, - ): Promise> { - this.logger(`Deploying MerkleRootHook to ${chain}`); - const merkleTreeHook = await this.deployContract(chain, 'hook', [ - this.mailboxes[chain], - ]); - return { - hook: merkleTreeHook, - }; - } - - async deployIsmContracts( - chain: ChainName, - config: MultisigIsmConfig, - ): Promise> { - const ism = await this.ismFactory.deploy(chain, config); - if (config.type === ModuleType.MERKLE_ROOT_MULTISIG) { - this.logger(`Deploying StaticMerkleRootMultisigIsm to ${chain}`); - return { - ism: ism as StaticMerkleRootMultisigIsm, - }; - } else if (config.type === ModuleType.MESSAGE_ID_MULTISIG) { - this.logger(`Deploying StaticMessageIdMultisigIsm to ${chain}`); - return { - ism: ism as StaticMessageIdMultisigIsm, - }; - } else { - throw new Error( - `Unexpected ISM type ${config.type} for MerkleRootInterceptorDeployer`, - ); - } - } -} diff --git a/typescript/sdk/src/hook/contracts.ts b/typescript/sdk/src/hook/contracts.ts index 7a32b3e986..36fb6f5b73 100644 --- a/typescript/sdk/src/hook/contracts.ts +++ b/typescript/sdk/src/hook/contracts.ts @@ -1,30 +1,9 @@ -import { - MerkleTreeHook__factory, - StaticMerkleRootMultisigIsm__factory, - StaticMessageIdMultisigIsm__factory, -} from '@hyperlane-xyz/core'; +import { MerkleTreeHook__factory } from '@hyperlane-xyz/core'; -export const merkleRootHookFactories = { - hook: new MerkleTreeHook__factory(), +export const merkleTreeHookFactories = { + merkleTreeHook: new MerkleTreeHook__factory(), }; +export const hookFactories = merkleTreeHookFactories; +export type MerkleTreeHookFactory = typeof merkleTreeHookFactories; -export const messageIdMultisigIsmFactory = { - ism: new StaticMessageIdMultisigIsm__factory(), -}; - -export type MerkleRootHookFactories = typeof merkleRootHookFactories; -export type MultisigIsmFactories = - | typeof merkleRootIsmFactories - | typeof messageIdMultisigIsmFactory; - -export const merkleRootIsmFactories = { - ism: new StaticMerkleRootMultisigIsm__factory(), -}; - -export type MerkleRootInterceptorFactories = MerkleRootHookFactories & - MultisigIsmFactories; - -export type HookFactories = MerkleRootHookFactories; -export type IsmFactories = MultisigIsmFactories; - -export type InterceptorFactories = HookFactories & IsmFactories; +export type HookFactories = MerkleTreeHookFactory; diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index a14944eb1a..6163a810c6 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -1,18 +1,9 @@ -import type { MultisigIsmConfig } from '../ism/types'; - export enum HookType { - MERKLE_ROOT_HOOK = 'merkleRootHook', + MERKLE_TREE_HOOK = 'merkleTreeHook', } -export type MerkleRootHookConfig = { - type: HookType.MERKLE_ROOT_HOOK; -}; - -export type MerkleRootInterceptorConfig = { - hook: MerkleRootHookConfig; - ism: MultisigIsmConfig; +export type MerkleTreeHookConfig = { + type: HookType.MERKLE_TREE_HOOK; }; -export type HookConfig = MerkleRootHookConfig; - -export type InterceptorConfig = MerkleRootInterceptorConfig; +export type HookConfig = MerkleTreeHookConfig; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 25dadc56cd..bddd4d0256 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -108,13 +108,8 @@ export { IgpViolationType, OverheadIgpConfig, } from './gas/types'; -export { MerkleRootInterceptorDeployer } from './hook/MerkleRootInterceptorDeployer'; -export { - HookConfig, - HookType, - InterceptorConfig, - MerkleRootHookConfig, -} from './hook/types'; +export { HyperlaneHookDeployer } from './hook/HyperlaneHookDeployer'; +export { HookConfig, HookType, MerkleTreeHookConfig } from './hook/types'; export { HyperlaneIsmFactory, collectValidators, From a00dc4ea73644027148b2b8b8b78c90d9e36f2a8 Mon Sep 17 00:00:00 2001 From: -f Date: Mon, 2 Oct 2023 16:04:44 -0400 Subject: [PATCH 15/18] fix redundant return false --- typescript/sdk/src/ism/HyperlaneIsmFactory.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index c187924fdd..2e14cbbda4 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -324,7 +324,6 @@ export async function moduleCanCertainlyVerify( } } } - return false; } export async function moduleMatchesConfig( From 86f8b0b62ade8f20d887afee46804c0d93691750 Mon Sep 17 00:00:00 2001 From: -f Date: Mon, 2 Oct 2023 16:09:01 -0400 Subject: [PATCH 16/18] left out hyperlaneHookDeployert --- .../sdk/src/hook/HyperlaneHookDeployer.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 typescript/sdk/src/hook/HyperlaneHookDeployer.ts diff --git a/typescript/sdk/src/hook/HyperlaneHookDeployer.ts b/typescript/sdk/src/hook/HyperlaneHookDeployer.ts new file mode 100644 index 0000000000..0791eaf123 --- /dev/null +++ b/typescript/sdk/src/hook/HyperlaneHookDeployer.ts @@ -0,0 +1,55 @@ +import debug from 'debug'; + +import { Address } from '@hyperlane-xyz/utils'; + +import { HyperlaneContracts } from '../contracts/types'; +import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; +import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; +import { MultiProvider } from '../providers/MultiProvider'; +import { ChainMap, ChainName } from '../types'; + +import { + HookFactories, + MerkleTreeHookFactory, + hookFactories, +} from './contracts'; +import { HookConfig, HookType } from './types'; + +export class HyperlaneHookDeployer extends HyperlaneDeployer< + HookConfig, + HookFactories +> { + constructor( + multiProvider: MultiProvider, + readonly ismFactory: HyperlaneIsmFactory, + readonly mailboxes: ChainMap
, + ) { + super(multiProvider, hookFactories, { + logger: debug('hyperlane:HyperlaneHookDeployer'), + }); + } + + async deployContracts( + chain: ChainName, + config: HookConfig, + ): Promise> { + if (config.type === HookType.MERKLE_TREE_HOOK) { + return this.deployMerleTreeHook(chain, config); + } else { + throw new Error(`Unsupported hook type: ${config.type}`); + } + } + + async deployMerleTreeHook( + chain: ChainName, + _: HookConfig, + ): Promise> { + this.logger(`Deploying MerkleTreeHook to ${chain}`); + const merkleTreeHook = await this.deployContract(chain, 'merkleTreeHook', [ + this.mailboxes[chain], + ]); + return { + merkleTreeHook: merkleTreeHook, + }; + } +} From cc489429651df7d0b3df16bfad76594c549d929f Mon Sep 17 00:00:00 2001 From: -f Date: Mon, 2 Oct 2023 16:49:16 -0400 Subject: [PATCH 17/18] spelling fixes --- typescript/sdk/src/hook/HyperlaneHookDeployer.ts | 4 ++-- typescript/sdk/src/hook/contracts.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/typescript/sdk/src/hook/HyperlaneHookDeployer.ts b/typescript/sdk/src/hook/HyperlaneHookDeployer.ts index 0791eaf123..85077a4a4c 100644 --- a/typescript/sdk/src/hook/HyperlaneHookDeployer.ts +++ b/typescript/sdk/src/hook/HyperlaneHookDeployer.ts @@ -34,13 +34,13 @@ export class HyperlaneHookDeployer extends HyperlaneDeployer< config: HookConfig, ): Promise> { if (config.type === HookType.MERKLE_TREE_HOOK) { - return this.deployMerleTreeHook(chain, config); + return this.deployMerkleTreeHook(chain, config); } else { throw new Error(`Unsupported hook type: ${config.type}`); } } - async deployMerleTreeHook( + async deployMerkleTreeHook( chain: ChainName, _: HookConfig, ): Promise> { diff --git a/typescript/sdk/src/hook/contracts.ts b/typescript/sdk/src/hook/contracts.ts index 36fb6f5b73..2fb99b4494 100644 --- a/typescript/sdk/src/hook/contracts.ts +++ b/typescript/sdk/src/hook/contracts.ts @@ -1,9 +1,9 @@ import { MerkleTreeHook__factory } from '@hyperlane-xyz/core'; -export const merkleTreeHookFactories = { +export const merkleTreeHookFactory = { merkleTreeHook: new MerkleTreeHook__factory(), }; -export const hookFactories = merkleTreeHookFactories; -export type MerkleTreeHookFactory = typeof merkleTreeHookFactories; +export const hookFactories = merkleTreeHookFactory; +export type MerkleTreeHookFactory = typeof merkleTreeHookFactory; export type HookFactories = MerkleTreeHookFactory; From 2a03eab8bd4c97c2a36fc9626fdb0f272587f012 Mon Sep 17 00:00:00 2001 From: -f Date: Mon, 2 Oct 2023 18:59:36 -0400 Subject: [PATCH 18/18] revert testnet_config.json --- rust/config/testnet_config.json | 158 ++++++++++++++++++++++++++++---- 1 file changed, 139 insertions(+), 19 deletions(-) diff --git a/rust/config/testnet_config.json b/rust/config/testnet_config.json index d5f52a58d9..baf249942c 100644 --- a/rust/config/testnet_config.json +++ b/rust/config/testnet_config.json @@ -1,42 +1,162 @@ { "chains": { - "test1": { - "name": "test1", - "domain": 13371, + "alfajores": { + "name": "alfajores", + "domain": 44787, "addresses": { - "mailbox": "0x975Ab64F4901Af5f0C96636deA0b9de3419D0c2F", - "validatorAnnounce": "0x742489F22807ebB4C36ca6cD95c3e1C044B7B6c8" + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" }, "protocol": "ethereum", "finalityBlocks": 0, "index": { - "from": 322 + "from": 14863532 } }, - "test2": { - "name": "test2", - "domain": 13372, + "fuji": { + "name": "fuji", + "domain": 43113, "addresses": { - "mailbox": "0x3fdc08D815cc4ED3B7F69Ee246716f2C8bCD6b07", - "validatorAnnounce": "0x2A590C461Db46bca129E8dBe5C3998A8fF402e76" + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" }, "protocol": "ethereum", - "finalityBlocks": 1, + "finalityBlocks": 3, + "index": { + "from": 16330615 + } + }, + "mumbai": { + "name": "mumbai", + "domain": 80001, + "addresses": { + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + }, + "protocol": "ethereum", + "finalityBlocks": 32, + "index": { + "from": 29390033 + } + }, + "bsctestnet": { + "name": "bsctestnet", + "domain": 97, + "addresses": { + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + }, + "protocol": "ethereum", + "finalityBlocks": 9, + "index": { + "from": 25001629 + } + }, + "goerli": { + "name": "goerli", + "domain": 5, + "addresses": { + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + }, + "protocol": "ethereum", + "finalityBlocks": 2, "index": { - "from": 322 + "from": 8039005 } }, - "test3": { - "name": "test3", - "domain": 13373, + "sepolia": { + "name": "sepolia", + "domain": 11155111, "addresses": { - "mailbox": "0x9849832a1d8274aaeDb1112ad9686413461e7101", - "validatorAnnounce": "0x262e2b50219620226C5fB5956432A88fffd94Ba7" + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" }, "protocol": "ethereum", "finalityBlocks": 2, "index": { - "from": 322 + "from": 3082913 + } + }, + "moonbasealpha": { + "name": "moonbasealpha", + "domain": 1287, + "addresses": { + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + }, + "protocol": "ethereum", + "finalityBlocks": 1, + "index": { + "from": 3310405 + } + }, + "optimismgoerli": { + "name": "optimismgoerli", + "domain": 420, + "addresses": { + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + }, + "protocol": "ethereum", + "finalityBlocks": 1, + "index": { + "from": 3055263 + } + }, + "arbitrumgoerli": { + "name": "arbitrumgoerli", + "domain": 421613, + "addresses": { + "mailbox": "0xCC737a94FecaeC165AbCf12dED095BB13F037685", + "interchainGasPaymaster": "0x8f9C3888bFC8a5B25AED115A82eCbb788b196d2a", + "validatorAnnounce": "0x3Fc742696D5dc9846e04f7A1823D92cb51695f9a" + }, + "protocol": "ethereum", + "finalityBlocks": 1, + "index": { + "from": 1941997 + } + }, + "solanadevnet": { + "name": "solanadevnet", + "domain": 1399811151, + "addresses": { + "mailbox": "4v25Dz9RccqUrTzmfHzJMsjd1iVoNrWzeJ4o6GYuJrVn", + "interchainGasPaymaster": "7hMPEGdgBQFsjEz3aaNwZp8WMFHs615zAM3erXBDJuJR", + "validatorAnnounce": "CMHKvdq4CopDf7qXnDCaTybS15QekQeRt4oUB219yxsp" + }, + "protocol": "sealevel", + "finalityBlocks": 0, + "connection": { + "type": "http", + "url": "https://api.devnet.solana.com" + }, + "index": { + "from": 1, + "mode": "sequence" + } + }, + "proteustestnet": { + "name": "proteustestnet", + "domain": 88002, + "addresses": { + "mailbox": "0x918D3924Fad8F71551D9081172e9Bb169745461e", + "interchainGasPaymaster": "0x06b62A9F5AEcc1E601D0E02732b4E1D0705DE7Db", + "validatorAnnounce": "0xEEea93d0d0287c71e47B3f62AFB0a92b9E8429a1" + }, + "protocol": "ethereum", + "finalityBlocks": 1, + "index": { + "from": 8609588 } } }