Skip to content

Commit

Permalink
feat: update warp remote router schema (#4948)
Browse files Browse the repository at this point in the history
### Description

Updates the Warp route remote routers schema to be closer to the
remoteIcaRouters schema from core apply

### Drive-by changes

- dedup remote ica routes schema 

### Related issues

### Backward compatibility

- No this will break the current remote routers schema for the warp
deployment config

### Testing

- Manual, E2E

---------

Co-authored-by: Paul Balaji <10051819+paulbalaji@users.noreply.github.com>
  • Loading branch information
xeno097 and paulbalaji authored Dec 4, 2024
1 parent 323f0f1 commit aa1ea9a
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 33 deletions.
6 changes: 6 additions & 0 deletions .changeset/silver-peas-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@hyperlane-xyz/cli': minor
'@hyperlane-xyz/sdk': minor
---

updates the warp deployment config schema to be closer to the ica routing schema
5 changes: 3 additions & 2 deletions typescript/cli/src/deploy/warp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -731,8 +731,9 @@ async function enrollRemoteRouters(

mutatedWarpRouteConfig.remoteRouters =
otherChains.reduce<RemoteRouters>((remoteRouters, otherChain) => {
remoteRouters[multiProvider.getDomainId(otherChain)] =
deployedRoutersAddresses[otherChain];
remoteRouters[multiProvider.getDomainId(otherChain)] = {
address: deployedRoutersAddresses[otherChain],
};
return remoteRouters;
}, {});

Expand Down
26 changes: 10 additions & 16 deletions typescript/sdk/src/ica/schemas.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { z } from 'zod';

import { ZHash } from '../metadata/customZodTypes.js';
import { RemoteRouterDomain, RemoteRouterRouter } from '../router/types.js';
import { DerivedOwnableSchema } from '../schemas.js';

export const RemoteIcaRouterConfigSchema = z.record(
z.string(),
z.object({
address: ZHash,
interchainSecurityModule: ZHash.optional(),
}),
RemoteRouterDomain,
RemoteRouterRouter.merge(
z.object({
interchainSecurityModule: ZHash.optional().describe(
'Optional ISM override to be used on the chain',
),
}),
),
);

export const IcaRouterConfigSchema = z.object({
Expand All @@ -21,23 +25,13 @@ export const IcaRouterConfigSchema = z.object({
remoteIcaRouters: RemoteIcaRouterConfigSchema.optional(),
});

export const DerivedRemoteIcaRouterConfigSchema = z.record(
z.string(),
z.object({
address: ZHash,
interchainSecurityModule: ZHash.optional().describe(
'Optional ISM override to be used on the chain',
),
}),
);

export const DerivedIcaRouterConfigSchema = DerivedOwnableSchema.merge(
z
.object({
owner: ZHash,
mailbox: ZHash,
proxyAdmin: DerivedOwnableSchema,
remoteIcaRouters: DerivedRemoteIcaRouterConfigSchema,
remoteIcaRouters: RemoteIcaRouterConfigSchema,
})
.strict(),
);
6 changes: 4 additions & 2 deletions typescript/sdk/src/router/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ export const ForeignDeploymentConfigSchema = z.object({
foreignDeployment: z.string().optional(),
});

const RemoteRouterDomain = z.string();
const RemoteRouterRouter = z.string().startsWith('0x');
export const RemoteRouterDomain = z.string();
export const RemoteRouterRouter = z.object({
address: z.string().startsWith('0x'),
});
export const RemoteRoutersSchema = z.record(
RemoteRouterDomain,
RemoteRouterRouter,
Expand Down
12 changes: 9 additions & 3 deletions typescript/sdk/src/token/EvmERC20WarpModule.hardhat-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ import { TokenRouterConfig } from './schemas.js';
const randomRemoteRouters = (n: number) => {
const routers: RemoteRouters = {};
for (let domain = 0; domain < n; domain++) {
routers[domain] = randomAddress();
routers[domain] = {
address: randomAddress(),
};
}
return routers;
};
Expand Down Expand Up @@ -580,7 +582,9 @@ describe('EvmERC20WarpHyperlaneModule', async () => {
txs = await evmERC20WarpModule.update({
...config,
remoteRouters: {
3: randomAddress(),
3: {
address: randomAddress(),
},
},
});

Expand Down Expand Up @@ -679,7 +683,9 @@ describe('EvmERC20WarpHyperlaneModule', async () => {
...baseConfig,
type: TokenType.native,
remoteRouters: {
[domain]: randomAddress(),
[domain]: {
address: randomAddress(),
},
},
};

Expand Down
23 changes: 17 additions & 6 deletions typescript/sdk/src/token/EvmERC20WarpModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,25 @@ export class EvmERC20WarpModule extends HyperlaneModule<
return [];
}

// We normalize the addresses for comparison
actualConfig.remoteRouters = normalizeConfig(actualConfig.remoteRouters);
expectedConfig.remoteRouters = normalizeConfig(
expectedConfig.remoteRouters,
);
assert(actualConfig.remoteRouters, 'actualRemoteRouters is undefined');
assert(expectedConfig.remoteRouters, 'actualRemoteRouters is undefined');

// We normalize the addresses for comparison
actualConfig.remoteRouters = Object.fromEntries(
Object.entries(actualConfig.remoteRouters).map(([key, value]) => [
key,
// normalizeConfig removes the address property but we don't want to lose that info
{ ...normalizeConfig(value), address: normalizeConfig(value.address) },
]),
);
expectedConfig.remoteRouters = Object.fromEntries(
Object.entries(expectedConfig.remoteRouters).map(([key, value]) => [
key,
// normalizeConfig removes the address property but we don't want to lose that info
{ ...normalizeConfig(value), address: normalizeConfig(value.address) },
]),
);

const { remoteRouters: actualRemoteRouters } = actualConfig;
const { remoteRouters: expectedRemoteRouters } = expectedConfig;

Expand All @@ -171,7 +182,7 @@ export class EvmERC20WarpModule extends HyperlaneModule<
[
Object.keys(expectedRemoteRouters).map((k) => Number(k)),
Object.values(expectedRemoteRouters).map((a) =>
addressToBytes32(a),
addressToBytes32(a.address),
),
],
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ describe('ERC20WarpRouterReader', async () => {
);
expect(Object.keys(derivedConfig.remoteRouters!).length).to.equal(1);
expect(
derivedConfig.remoteRouters![otherChainMetadata.domainId!],
derivedConfig.remoteRouters![otherChainMetadata.domainId!].address,
).to.be.equal(warpRoute[otherChain].collateral.address);
});
});
15 changes: 12 additions & 3 deletions typescript/sdk/src/token/EvmERC20WarpRouteReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ import { DeployedOwnableConfig } from '../deploy/types.js';
import { EvmHookReader } from '../hook/EvmHookReader.js';
import { EvmIsmReader } from '../ism/EvmIsmReader.js';
import { MultiProvider } from '../providers/MultiProvider.js';
import { DestinationGas, RemoteRouters } from '../router/types.js';
import {
DestinationGas,
RemoteRouters,
RemoteRoutersSchema,
} from '../router/types.js';
import { ChainNameOrId } from '../types.js';
import { HyperlaneReader } from '../utils/HyperlaneReader.js';

Expand Down Expand Up @@ -267,13 +271,18 @@ export class EvmERC20WarpRouteReader extends HyperlaneReader {
);
const domains = await warpRoute.domains();

return Object.fromEntries(
const routers = Object.fromEntries(
await Promise.all(
domains.map(async (domain) => {
return [domain, bytes32ToAddress(await warpRoute.routers(domain))];
return [
domain,
{ address: bytes32ToAddress(await warpRoute.routers(domain)) },
];
}),
),
);

return RemoteRoutersSchema.parse(routers);
}

async fetchProxyAdminConfig(
Expand Down

0 comments on commit aa1ea9a

Please sign in to comment.