Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ergonomics of fork tests #2911

Merged
merged 8 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,12 @@ jobs:
strategy:
matrix:
environment: [testnet4, mainnet3]
module: [ism, core, helloworld]
module: [core, igp, helloworld]
include:
- environment: testnet4
chain: sepolia
- environment: mainnet3
chain: arbitrum

steps:
- uses: actions/checkout@v3
Expand All @@ -255,8 +260,8 @@ jobs:
!./rust
key: ${{ github.sha }}

- name: Test ${{ matrix.environment }} ${{ matrix.module }} deployment (check, deploy, govern, check again)
run: cd typescript/infra && ./fork.sh ${{ matrix.environment }} ${{ matrix.module }}
- name: Fork test ${{ matrix.environment }} ${{ matrix.module }} ${{ matrix.chain }} deployment
run: cd typescript/infra && ./fork.sh ${{ matrix.environment }} ${{ matrix.module }} ${{ matrix.chain }}

coverage:
runs-on: ubuntu-latest
Expand Down
20 changes: 7 additions & 13 deletions typescript/infra/config/environments/mainnet3/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { objMap } from '@hyperlane-xyz/utils';

import { supportedChainNames } from './chains';
import { igp } from './igp';
import { owners, safes } from './owners';
import { owners } from './owners';

export const core: ChainMap<CoreConfig> = objMap(owners, (local, owner) => {
const originMultisigs: ChainMap<MultisigConfig> = Object.fromEntries(
Expand Down Expand Up @@ -50,12 +50,12 @@ export const core: ChainMap<CoreConfig> = objMap(owners, (local, owner) => {
threshold: 1,
}),
),
owner,
...owner,
};

const pausableIsm: PausableIsmConfig = {
type: IsmType.PAUSABLE,
owner,
...owner,
};

const defaultIsm: AggregationIsmConfig = {
Expand All @@ -75,7 +75,7 @@ export const core: ChainMap<CoreConfig> = objMap(owners, (local, owner) => {

const pausableHook: PausableHookConfig = {
type: HookType.PAUSABLE,
owner,
...owner,
};

const defaultHook: AggregationHookConfig = {
Expand All @@ -87,20 +87,14 @@ export const core: ChainMap<CoreConfig> = objMap(owners, (local, owner) => {
type: HookType.PROTOCOL_FEE,
maxProtocolFee: ethers.utils.parseUnits('1', 'gwei').toString(), // 1 gwei of native token
protocolFee: BigNumber.from(0).toString(), // 0 wei
beneficiary: owner,
owner,
beneficiary: owner.owner,
...owner,
};

return {
owner,
defaultIsm,
defaultHook,
requiredHook,
ownerOverrides: {
proxyAdmin:
local === 'arbitrum'
? `0xAC98b0cD1B64EA4fe133C6D2EDaf842cE5cF4b01`
: safes[local] ?? owner,
},
...owner,
};
});
2 changes: 1 addition & 1 deletion typescript/infra/config/environments/mainnet3/igp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function getGasOracles(local: MainnetChains) {
}

export const igp: ChainMap<IgpConfig> = objMap(owners, (chain, owner) => ({
owner,
...owner,
oracleKey: DEPLOYER_ADDRESS,
beneficiary: KEY_FUNDER_ADDRESS,
gasOracleType: getGasOracles(chain),
Expand Down
26 changes: 16 additions & 10 deletions typescript/infra/config/environments/mainnet3/owners.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { ChainMap } from '@hyperlane-xyz/sdk';
import { ChainMap, OwnableConfig } from '@hyperlane-xyz/sdk';
import { Address, objMap } from '@hyperlane-xyz/utils';

export const safes: ChainMap<Address> = {
export const timelocks: ChainMap<Address | undefined> = {
arbitrum: '0xAC98b0cD1B64EA4fe133C6D2EDaf842cE5cF4b01',
};

export const safes: ChainMap<Address | undefined> = {
celo: '0x1DE69322B55AC7E0999F8e7738a1428C8b130E4d',
ethereum: '0x12C5AB61Fe17dF9c65739DBa73dF294708f78d23',
avalanche: '0xDF9B28B76877f1b1B4B8a11526Eb7D8D7C49f4f3',
Expand All @@ -13,14 +17,16 @@ export const safes: ChainMap<Address> = {
gnosis: '0x36b0AA0e7d04e7b825D7E409FEa3c9A3d57E4C22',
// solana: 'EzppBFV2taxWw8kEjxNYvby6q7W1biJEqwP3iC7YgRe3',
// TODO: create gnosis safes here
base: '0xa7ECcdb9Be08178f896c26b7BbD8C3D4E844d9Ba',
scroll: '0xa7ECcdb9Be08178f896c26b7BbD8C3D4E844d9Ba',
polygonzkevm: '0xa7ECcdb9Be08178f896c26b7BbD8C3D4E844d9Ba',
mantapacific: '0xa7ECcdb9Be08178f896c26b7BbD8C3D4E844d9Ba',
base: undefined,
scroll: undefined,
polygonzkevm: undefined,
mantapacific: undefined,
};
yorhodes marked this conversation as resolved.
Show resolved Hide resolved

// export const owners = safes;

// temporarily keep ownership on deployer key
const deployer = '0xa7ECcdb9Be08178f896c26b7BbD8C3D4E844d9Ba';
export const owners = objMap(safes, (_, __) => deployer);
export const owners: ChainMap<OwnableConfig> = objMap(safes, (local, __) => ({
owner: deployer, // TODO: change this to the safe
ownerOverrides: {
proxyAdmin: timelocks[local] ?? safes[local] ?? deployer,
},
}));
10 changes: 5 additions & 5 deletions typescript/infra/config/environments/test/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { owners } from './owners';
export const core: ChainMap<CoreConfig> = objMap(owners, (local, owner) => {
const defaultIsm: RoutingIsmConfig = {
type: IsmType.ROUTING,
owner,
...owner,
domains: Object.fromEntries(
Object.entries(chainToValidator)
.filter(([chain, _]) => chain !== local)
Expand All @@ -46,7 +46,7 @@ export const core: ChainMap<CoreConfig> = objMap(owners, (local, owner) => {

const defaultHook: FallbackRoutingHookConfig = {
type: HookType.FALLBACK_ROUTING,
owner,
...owner,
fallback: merkleHook,
domains: Object.fromEntries(
Object.entries(chainToValidator)
Expand All @@ -59,14 +59,14 @@ export const core: ChainMap<CoreConfig> = objMap(owners, (local, owner) => {
type: HookType.PROTOCOL_FEE,
maxProtocolFee: ethers.utils.parseUnits('1', 'gwei').toString(), // 1 gwei of native token
protocolFee: BigNumber.from(1).toString(), // 1 wei
beneficiary: owner,
owner,
beneficiary: owner.owner,
...owner,
};

return {
owner,
defaultIsm,
defaultHook,
requiredHook,
...owner,
};
});
8 changes: 4 additions & 4 deletions typescript/infra/config/environments/test/igp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function getGasOracles(local: TestChains) {
);
}

export const igp: ChainMap<IgpConfig> = objMap(owners, (chain, owner) => {
export const igp: ChainMap<IgpConfig> = objMap(owners, (chain, ownerConfig) => {
const overhead = Object.fromEntries(
exclude(chain, chainNames).map((remote) => [
remote,
Expand All @@ -30,10 +30,10 @@ export const igp: ChainMap<IgpConfig> = objMap(owners, (chain, owner) => {
]),
);
return {
owner,
oracleKey: owner,
beneficiary: owner,
oracleKey: ownerConfig.owner,
beneficiary: ownerConfig.owner,
gasOracleType: getGasOracles(chain),
overhead,
...ownerConfig,
};
});
7 changes: 3 additions & 4 deletions typescript/infra/config/environments/test/owners.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { ChainMap } from '@hyperlane-xyz/sdk';
import { Address } from '@hyperlane-xyz/utils';
import { ChainMap, OwnableConfig } from '@hyperlane-xyz/sdk';

import { chainNames } from './chains';

// Owner is hardhat account 0
const OWNER_ADDRESS = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266';
export const owners: ChainMap<Address> = Object.fromEntries(
chainNames.map((chain) => [chain, OWNER_ADDRESS]),
export const owners: ChainMap<OwnableConfig> = Object.fromEntries(
chainNames.map((chain) => [chain, { owner: OWNER_ADDRESS }]),
);
147 changes: 75 additions & 72 deletions typescript/infra/config/environments/testnet4/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,87 +24,90 @@ import { supportedChainNames } from './chains';
import { igp } from './igp';
import { owners } from './owners';

export const core: ChainMap<CoreConfig> = objMap(owners, (local, owner) => {
const originMultisigs: ChainMap<MultisigConfig> = Object.fromEntries(
supportedChainNames
.filter((chain) => chain !== local)
.map((origin) => [origin, defaultMultisigConfigs[origin]]),
);
export const core: ChainMap<CoreConfig> = objMap(
owners,
(local, ownerConfig) => {
const originMultisigs: ChainMap<MultisigConfig> = Object.fromEntries(
supportedChainNames
.filter((chain) => chain !== local)
.map((origin) => [origin, defaultMultisigConfigs[origin]]),
);

const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => ({
type: IsmType.MERKLE_ROOT_MULTISIG,
...multisig,
});
const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => ({
type: IsmType.MERKLE_ROOT_MULTISIG,
...multisig,
});

const messageIdIsm = (multisig: MultisigConfig): MultisigIsmConfig => ({
type: IsmType.MESSAGE_ID_MULTISIG,
...multisig,
});
const messageIdIsm = (multisig: MultisigConfig): MultisigIsmConfig => ({
type: IsmType.MESSAGE_ID_MULTISIG,
...multisig,
});

const routingIsm: RoutingIsmConfig = {
type: IsmType.ROUTING,
domains: objMap(
originMultisigs,
(_, multisig): AggregationIsmConfig => ({
type: IsmType.AGGREGATION,
modules: [messageIdIsm(multisig), merkleRoot(multisig)],
threshold: 1,
}),
),
owner,
};
const routingIsm: RoutingIsmConfig = {
type: IsmType.ROUTING,
domains: objMap(
originMultisigs,
(_, multisig): AggregationIsmConfig => ({
type: IsmType.AGGREGATION,
modules: [messageIdIsm(multisig), merkleRoot(multisig)],
threshold: 1,
}),
),
...ownerConfig,
};

const pausableIsm: PausableIsmConfig = {
type: IsmType.PAUSABLE,
owner,
};
const pausableIsm: PausableIsmConfig = {
type: IsmType.PAUSABLE,
...ownerConfig,
};

const defaultIsm: AggregationIsmConfig = {
type: IsmType.AGGREGATION,
modules: [routingIsm, pausableIsm],
threshold: 2,
};
const defaultIsm: AggregationIsmConfig = {
type: IsmType.AGGREGATION,
modules: [routingIsm, pausableIsm],
threshold: 2,
};

const merkleHook: MerkleTreeHookConfig = {
type: HookType.MERKLE_TREE,
};
const merkleHook: MerkleTreeHookConfig = {
type: HookType.MERKLE_TREE,
};

const igpHook: IgpHookConfig = {
type: HookType.INTERCHAIN_GAS_PAYMASTER,
...igp[local],
};
const igpHook: IgpHookConfig = {
type: HookType.INTERCHAIN_GAS_PAYMASTER,
...igp[local],
};

const pausableHook: PausableHookConfig = {
type: HookType.PAUSABLE,
owner,
};
const pausableHook: PausableHookConfig = {
type: HookType.PAUSABLE,
...ownerConfig,
};

const aggregationHooks = objMap(
originMultisigs,
(_origin, _): AggregationHookConfig => ({
type: HookType.AGGREGATION,
hooks: [pausableHook, merkleHook, igpHook],
}),
);
const aggregationHooks = objMap(
originMultisigs,
(_origin, _): AggregationHookConfig => ({
type: HookType.AGGREGATION,
hooks: [pausableHook, merkleHook, igpHook],
}),
);

const defaultHook: DomainRoutingHookConfig = {
type: HookType.ROUTING,
owner,
domains: aggregationHooks,
};
const defaultHook: DomainRoutingHookConfig = {
type: HookType.ROUTING,
domains: aggregationHooks,
...ownerConfig,
};

const requiredHook: ProtocolFeeHookConfig = {
type: HookType.PROTOCOL_FEE,
maxProtocolFee: ethers.utils.parseUnits('1', 'gwei').toString(), // 1 gwei of native token
protocolFee: BigNumber.from(1).toString(), // 1 wei of native token
beneficiary: owner,
owner,
};
const requiredHook: ProtocolFeeHookConfig = {
type: HookType.PROTOCOL_FEE,
maxProtocolFee: ethers.utils.parseUnits('1', 'gwei').toString(), // 1 gwei of native token
protocolFee: BigNumber.from(1).toString(), // 1 wei of native token
beneficiary: ownerConfig.owner,
...ownerConfig,
};

return {
owner,
defaultIsm,
defaultHook,
requiredHook,
};
});
return {
defaultIsm,
defaultHook,
requiredHook,
...ownerConfig,
};
},
);
8 changes: 4 additions & 4 deletions typescript/infra/config/environments/testnet4/igp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ function getGasOracles(local: TestnetChains) {
);
}

export const igp: ChainMap<IgpConfig> = objMap(owners, (chain, owner) => {
export const igp: ChainMap<IgpConfig> = objMap(owners, (chain, ownerConfig) => {
return {
owner,
oracleKey: owner,
beneficiary: owner,
...ownerConfig,
oracleKey: ownerConfig.owner,
beneficiary: ownerConfig.owner,
gasOracleType: getGasOracles(chain),
overhead: Object.fromEntries(
exclude(chain, supportedChainNames).map((remote) => [
Expand Down
Loading
Loading