Skip to content

Commit

Permalink
No metadata relayer support for hooks (#2495)
Browse files Browse the repository at this point in the history
### Description

- Adding `NoMetadataRelayer` moduleType which returns an empty `vec![]`
on `MetadataBuilder::build()`
- Adding `HyperlaneHookDeployer` which lets you deploy the hook, ISM and
a testRecipient which specifies to use the `AbtractNativeISM`
### Drive-by changes

- none

### Related issues

- Accompanies #2316 
- Fixes hyperlane-xyz/issues#379 for Optimism
- Related to adding native hooks to Mailbox V3
hyperlane-xyz/issues#486

### Backward compatibility

Backward compatible? Yes

Tooling changes needed? Need to update node to ^18

### Testing

- Manual on testnet3
  • Loading branch information
aroralanuk authored Jul 11, 2023
1 parent f7e453a commit d69a3f6
Show file tree
Hide file tree
Showing 23 changed files with 430 additions and 7 deletions.
5 changes: 4 additions & 1 deletion rust/agents/relayer/src/msg/metadata/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ use crate::msg::metadata::multisig::{
LegacyMultisigMetadataBuilder, MerkleRootMultisigMetadataBuilder,
MessageIdMultisigMetadataBuilder,
};
use crate::msg::metadata::{AggregationIsmMetadataBuilder, RoutingIsmMetadataBuilder};
use crate::msg::metadata::{
AggregationIsmMetadataBuilder, NullMetadataBuilder, RoutingIsmMetadataBuilder,
};

#[derive(Debug, thiserror::Error)]
pub enum MetadataBuilderError {
Expand Down Expand Up @@ -84,6 +86,7 @@ impl MetadataBuilder for BaseMetadataBuilder {
ModuleType::MessageIdMultisig => Box::new(MessageIdMultisigMetadataBuilder::new(base)),
ModuleType::Routing => Box::new(RoutingIsmMetadataBuilder::new(base)),
ModuleType::Aggregation => Box::new(AggregationIsmMetadataBuilder::new(base)),
ModuleType::Null => Box::new(NullMetadataBuilder::new()),
_ => return Err(MetadataBuilderError::UnsupportedModuleType(module_type).into()),
};
metadata_builder
Expand Down
2 changes: 2 additions & 0 deletions rust/agents/relayer/src/msg/metadata/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod aggregation;
mod base;
mod multisig;
mod null_metadata;
mod routing;

use aggregation::AggregationIsmMetadataBuilder;
pub(crate) use base::BaseMetadataBuilder;
pub(crate) use base::MetadataBuilder;
use null_metadata::NullMetadataBuilder;
use routing::RoutingIsmMetadataBuilder;
21 changes: 21 additions & 0 deletions rust/agents/relayer/src/msg/metadata/null_metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use super::MetadataBuilder;
use async_trait::async_trait;
use derive_new::new;
use tracing::instrument;

use hyperlane_core::{HyperlaneMessage, H256};

#[derive(Clone, Debug, new)]
pub struct NullMetadataBuilder {}

#[async_trait]
impl MetadataBuilder for NullMetadataBuilder {
#[instrument(err, skip(self))]
async fn build(
&self,
_ism_address: H256,
_message: &HyperlaneMessage,
) -> eyre::Result<Option<Vec<u8>>> {
Ok(Some(vec![]))
}
}
2 changes: 1 addition & 1 deletion rust/agents/relayer/src/msg/pending_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ impl PendingMessage {
pm.next_attempt_after = next_attempt_after;
}
r => {
info!(message_id = ?pm.message.id(), result = ?r, "Failed to read retry count from HyperlaneDB for message.")
trace!(message_id = ?pm.message.id(), result = ?r, "Failed to read retry count from HyperlaneDB for message.")
}
}
pm
Expand Down
2 changes: 2 additions & 0 deletions rust/hyperlane-core/src/traits/interchain_security_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub enum ModuleType {
MerkleRootMultisig,
/// Message ID ISM (cheapest multisig with no batching)
MessageIdMultisig,
/// No metadata ISM (no metadata)
Null,
}

/// Interface for the InterchainSecurityModule chain contract. Allows abstraction over
Expand Down
4 changes: 2 additions & 2 deletions solidity/contracts/interfaces/IInterchainSecurityModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ pragma solidity >=0.6.11;

interface IInterchainSecurityModule {
enum Types {
NULL, // used with relayer carrying no metadata
UNUSED,
ROUTING,
AGGREGATION,
LEGACY_MULTISIG,
MERKLE_ROOT_MULTISIG,
MESSAGE_ID_MULTISIG,
OPTIMISM
NULL // used with relayer carrying no metadata
}

/**
Expand Down
35 changes: 35 additions & 0 deletions typescript/infra/config/environments/mainnet2/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
ChainMap,
HookConfig,
HookContractType,
MessageHookConfig,
NoMetadataIsmConfig,
filterByChains,
objMap,
} from '@hyperlane-xyz/sdk';

import { owners } from './owners';

const chainNameFilter = new Set(['ethereum', 'optimism']);
const filteredOwnersResult = filterByChains<string>(owners, chainNameFilter);

export const hooks: ChainMap<HookConfig> = objMap(
filteredOwnersResult,
(chain) => {
if (chain === 'ethereum') {
const hookConfig: MessageHookConfig = {
hookContractType: HookContractType.HOOK,
nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1',
remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first
destinationDomain: 10,
};
return hookConfig;
} else {
const ismConfig: NoMetadataIsmConfig = {
hookContractType: HookContractType.ISM,
nativeBridge: '0x4200000000000000000000000000000000000007',
};
return ismConfig;
}
},
);
2 changes: 2 additions & 0 deletions typescript/infra/config/environments/mainnet2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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';
Expand All @@ -37,6 +38,7 @@ export const environment: EnvironmentConfig = {
igp,
owners,
infra: infrastructure,
hooks,
helloWorld,
keyFunderConfig,
storageGasOracleConfig,
Expand Down
35 changes: 35 additions & 0 deletions typescript/infra/config/environments/test/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
ChainMap,
HookConfig,
HookContractType,
MessageHookConfig,
NoMetadataIsmConfig,
filterByChains,
objMap,
} from '@hyperlane-xyz/sdk';

import { owners } from './owners';

const chainNameFilter = new Set(['test1', 'test2']);
const filteredOwnersResult = filterByChains<string>(owners, chainNameFilter);

export const hooks: ChainMap<HookConfig> = objMap(
filteredOwnersResult,
(chain) => {
if (chain === 'test1') {
const hookConfig: MessageHookConfig = {
hookContractType: HookContractType.HOOK,
nativeBridge: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1',
remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first
destinationDomain: 10,
};
return hookConfig;
} else {
const ismConfig: NoMetadataIsmConfig = {
hookContractType: HookContractType.ISM,
nativeBridge: '0x4200000000000000000000000000000000000007',
};
return ismConfig;
}
},
);
2 changes: 2 additions & 0 deletions typescript/infra/config/environments/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ 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 { owners } from './owners';
Expand All @@ -17,6 +18,7 @@ export const environment: EnvironmentConfig = {
chainMetadataConfigs: testConfigs,
agents,
core,
hooks,
igp,
owners,
infra,
Expand Down
35 changes: 35 additions & 0 deletions typescript/infra/config/environments/testnet3/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
ChainMap,
HookConfig,
HookContractType,
MessageHookConfig,
NoMetadataIsmConfig,
filterByChains,
objMap,
} from '@hyperlane-xyz/sdk';

import { owners } from './owners';

const chainNameFilter = new Set(['goerli', 'optimismgoerli']);
const filteredOwnersResult = filterByChains<string>(owners, chainNameFilter);

export const hooks: ChainMap<HookConfig> = objMap(
filteredOwnersResult,
(chain) => {
if (chain === 'goerli') {
const hookConfig: MessageHookConfig = {
hookContractType: HookContractType.HOOK,
nativeBridge: '0x5086d1eEF304eb5284A0f6720f79403b4e9bE294',
remoteIsm: '0x4c5859f0f772848b2d91f1d83e2fe57935348029', // dummy, remoteISM should be deployed first
destinationDomain: 420,
};
return hookConfig;
} else {
const ismConfig: NoMetadataIsmConfig = {
hookContractType: HookContractType.ISM,
nativeBridge: '0x4200000000000000000000000000000000000007',
};
return ismConfig;
}
},
);
2 changes: 2 additions & 0 deletions typescript/infra/config/environments/testnet3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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';
Expand Down Expand Up @@ -38,6 +39,7 @@ export const environment: EnvironmentConfig = {
igp,
infra: infrastructure,
helloWorld,
hooks,
owners,
keyFunderConfig,
liquidityLayerConfig: {
Expand Down
1 change: 1 addition & 0 deletions typescript/infra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"deploy-core": "ts-node scripts/deploy.ts -e test --context hyperlane -m core",
"deploy-igp": "ts-node scripts/deploy.ts -e test --context hyperlane -m igp",
"deploy-ism": "ts-node scripts/deploy.ts -e test --context hyperlane -m ism",
"deploy-hook": "ts-node scripts/deploy.ts -e testnet3 --context hyperlane -m hook",
"build": "tsc",
"clean": "rm -rf ./dist ./cache",
"check": "tsc --noEmit",
Expand Down
4 changes: 4 additions & 0 deletions typescript/infra/scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ChainMap,
HyperlaneCoreDeployer,
HyperlaneDeployer,
HyperlaneHookDeployer,
HyperlaneIgp,
HyperlaneIgpDeployer,
HyperlaneIsmFactory,
Expand Down Expand Up @@ -63,6 +64,9 @@ async function main() {
multiProvider,
);
deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory);
} else if (module === Modules.HOOK) {
config = envConfig.hooks;
deployer = new HyperlaneHookDeployer(multiProvider);
} else if (module === Modules.INTERCHAIN_GAS_PAYMASTER) {
config = envConfig.igp;
deployer = new HyperlaneIgpDeployer(multiProvider);
Expand Down
23 changes: 23 additions & 0 deletions typescript/infra/scripts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ 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 } from '../src/utils/utils';

export enum Modules {
ISM_FACTORY = 'ism',
CORE = 'core',
HOOK = 'hook',
INTERCHAIN_GAS_PAYMASTER = 'igp',
INTERCHAIN_ACCOUNTS = 'ica',
INTERCHAIN_QUERY_SYSTEM = 'iqs',
Expand Down Expand Up @@ -290,3 +292,24 @@ export function getValidatorsByChain(
}
return validators;
}

export async function getHooksProvider(
multiProvider: MultiProvider,
environment: DeployEnvironment,
): Promise<MultiProvider> {
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;
}
2 changes: 2 additions & 0 deletions typescript/infra/src/config/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ChainMetadata,
ChainName,
CoreConfig,
HookConfig,
MultiProvider,
OverheadIgpConfig,
} from '@hyperlane-xyz/sdk';
Expand Down Expand Up @@ -35,6 +36,7 @@ export type EnvironmentConfig = {
// Each AgentConfig, keyed by the context
agents: Partial<Record<Contexts, RootAgentConfig>>;
core: ChainMap<CoreConfig>;
hooks: ChainMap<HookConfig>;
igp: ChainMap<OverheadIgpConfig>;
owners: ChainMap<types.Address>;
infra: InfrastructureConfig;
Expand Down
Loading

0 comments on commit d69a3f6

Please sign in to comment.