@ -23,9 +23,13 @@ import {
} from '@hyperlane-xyz/core' ;
import {
Address ,
Domain ,
eqAddress ,
formatMessage ,
normalizeAddress ,
objFilter ,
objMap ,
warn ,
} from '@hyperlane-xyz/utils' ;
import { HyperlaneApp } from '../app/HyperlaneApp' ;
@ -201,6 +205,22 @@ export class HyperlaneIsmFactory extends HyperlaneApp<ProxyFactoryFactories> {
const overrides = this . multiProvider . getTransactionOverrides ( destination ) ;
const routingIsmFactory = this . getContracts ( destination ) . routingIsmFactory ;
let routingIsm : DomainRoutingIsm | DefaultFallbackRoutingIsm ;
// filtering out domains which are not part of the multiprovider
config . domains = objFilter (
config . domains ,
( domain , config ) : config is IsmConfig = > {
const domainId = this . multiProvider . tryGetDomainId ( domain ) ;
if ( domainId === null ) {
warn (
` Domain ${ domain } doesn't have chain metadata provided, skipping ... ` ,
) ;
}
return domainId !== null ;
} ,
) ;
const safeConfigDomains = Object . keys ( config . domains ) . map ( ( domain ) = >
this . multiProvider . getDomainId ( domain ) ,
) ;
const delta : RoutingIsmDelta = existingIsmAddress
? await routingModuleDelta (
destination ,
@ -212,7 +232,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp<ProxyFactoryFactories> {
)
: {
domainsToUnenroll : [ ] ,
domainsToEnroll : Object.keys ( config . domains ) ,
domainsToEnroll : safeConfigDomains ,
} ;
const signer = this . multiProvider . getSigner ( destination ) ;
@ -227,13 +247,14 @@ export class HyperlaneIsmFactory extends HyperlaneApp<ProxyFactoryFactories> {
}
// reconfiguring existing routing ISM
if ( existingIsmAddress && isOwner && ! delta . mailbox ) {
const isms : ChainMap < Address > = { } ;
const isms : Record < Domain , Address > = { } ;
routingIsm = DomainRoutingIsm__factory . connect (
existingIsmAddress ,
this . multiProvider . getSigner ( destination ) ,
) ;
// deploying all the ISMs which have to be updated
for ( const origin of delta . domainsToEnroll ) {
for ( const originDomain of delta . domainsToEnroll ) {
const origin = this . multiProvider . getChainName ( originDomain ) ; // already filtered to only include domains in the multiprovider
logger (
` Reconfiguring preexisting routing ISM at for origin ${ origin } ... ` ,
) ;
@ -243,23 +264,20 @@ export class HyperlaneIsmFactory extends HyperlaneApp<ProxyFactoryFactories> {
origin ,
mailbox ,
} ) ;
isms [ origin ] = ism . address ;
isms [ originDomain ] = ism . address ;
const tx = await routingIsm . set (
this . multiProvider . getDomainId ( origin ) ,
isms [ origin ] ,
originDomain ,
isms [ originDomain ] ,
overrides ,
) ;
await this . multiProvider . handleTx ( destination , tx ) ;
}
// unenrolling domains if needed
for ( const origin of delta . domainsToUnenroll ) {
for ( const originDomain of delta . domainsToUnenroll ) {
logger (
` Unenrolling origin ${ origin } from preexisting routing ISM at ${ existingIsmAddress } ... ` ,
) ;
const tx = await routingIsm . remove (
this . multiProvider . getDomainId ( origin ) ,
overrides ,
` Unenrolling originDomain ${ originDomain } from preexisting routing ISM at ${ existingIsmAddress } ... ` ,
) ;
const tx = await routingIsm . remove ( originDomain , overrides ) ;
await this . multiProvider . handleTx ( destination , tx ) ;
}
// transfer ownership if needed
@ -280,9 +298,6 @@ export class HyperlaneIsmFactory extends HyperlaneApp<ProxyFactoryFactories> {
isms [ origin ] = ism . address ;
}
const submoduleAddresses = Object . values ( isms ) ;
const domains = Object . keys ( isms ) . map ( ( chain ) = >
this . multiProvider . getDomainId ( chain ) ,
) ;
let receipt : ethers.providers.TransactionReceipt ;
if ( config . type === IsmType . FALLBACK_ROUTING ) {
// deploying new fallback routing ISM
@ -302,7 +317,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp<ProxyFactoryFactories> {
destination ,
routingIsm [ 'initialize(address,uint32[],address[])' ] (
config . owner ,
d omains,
safeConfigD omains,
submoduleAddresses ,
overrides ,
) ,
@ -311,7 +326,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp<ProxyFactoryFactories> {
// deploying new domain routing ISM
const tx = await routingIsmFactory . deploy (
config . owner ,
d omains,
safeConfigD omains,
submoduleAddresses ,
overrides ,
) ;
@ -428,12 +443,17 @@ export async function moduleCanCertainlyVerify(
origin : ChainName ,
destination : ChainName ,
) : Promise < boolean > {
const originDomainId = multiProvider . tryGetDomainId ( origin ) ;
const destinationDomainId = multiProvider . tryGetDomainId ( destination ) ;
if ( ! originDomainId || ! destinationDomainId ) {
return false ;
}
const message = formatMessage (
0 ,
0 ,
multiProvider . getDomainId ( origin ) ,
originDomainId ,
ethers . constants . AddressZero ,
multiProvider . getDomainId ( destination ) ,
destinationDomainId ,
ethers . constants . AddressZero ,
'0x' ,
) ;
@ -689,7 +709,11 @@ export async function routingModuleDelta(
const routingIsm = DomainRoutingIsm__factory . connect ( module Address , provider ) ;
const owner = await routingIsm . owner ( ) ;
const deployedDomains = ( await routingIsm . domains ( ) ) . map ( ( domain ) = >
multiProvider . getChainName ( domain . toNumber ( ) ) ,
domain . toNumber ( ) ,
) ;
// config.domains is already filtered to only include domains in the multiprovider
const safeConfigDomains = objMap ( config . domains , ( domain ) = >
multiProvider . getDomainId ( domain ) ,
) ;
const delta : RoutingIsmDelta = {
@ -707,16 +731,15 @@ export async function routingModuleDelta(
}
// check for exclusion of domains in the config
delta . domainsToUnenroll = deployedDomains . filter (
( domain ) = > ! Object . keys ( config . d omains) . includes ( domain ) ,
( domain ) = > ! Object . values ( safeConfigD omains) . includes ( domain ) ,
) ;
// check for inclusion of domains in the config
for ( const [ origin , subConfig ] of Object . entries ( config . domains ) ) {
if ( ! deployedDomains . includes ( origin ) ) {
delta . domainsToEnroll . push ( origin ) ;
const originDomain = safeConfigDomains [ origin ] ;
if ( ! deployedDomains . includes ( originDomain ) ) {
delta . domainsToEnroll . push ( originDomain ) ;
} else {
const subModule = await routingIsm . module (
multiProvider . getDomainId ( origin ) ,
) ;
const subModule = await routingIsm . module ( originDomain ) ;
// Recursively check that the submodule for each configured
// domain matches the submodule config.
const subModuleMatches = await module MatchesConfig (
@ -725,9 +748,9 @@ export async function routingModuleDelta(
subConfig ,
multiProvider ,
contracts ,
origin ,
mailbox ,
) ;
if ( ! subModuleMatches ) delta . domainsToEnroll . push ( origin ) ;
if ( ! subModuleMatches ) delta . domainsToEnroll . push ( originDomain ) ;
}
}
return delta ;