From e317c6c85d9123c62693e9e924f9a56a48fdb738 Mon Sep 17 00:00:00 2001 From: Asa Oines Date: Tue, 20 Jun 2023 11:23:57 -0400 Subject: [PATCH] Sealevel chains should always use hex keys for relayers (#2402) ### Description This PR adds support for protocol-type awareness in infra. A new field `type` is added to chainMetadata. This field is inspected during key creation and relayer helm chart creation. Relayer keys for sealevel chains are set explicitly to always be hex keys. ### Drive-by changes None ### Related issues - https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/2350 ### Backward compatibility _Are these changes backward compatible?_ Yes --- typescript/infra/src/agents/key-utils.ts | 12 ++++-- typescript/infra/src/config/agent/relayer.ts | 37 ++++++++++++------- typescript/sdk/src/agents/types.ts | 10 ++--- .../sdk/src/consts/chainMetadata.test.ts | 7 +++- typescript/sdk/src/consts/chainMetadata.ts | 29 +++++++++++++++ typescript/sdk/src/index.ts | 1 + 6 files changed, 71 insertions(+), 25 deletions(-) diff --git a/typescript/infra/src/agents/key-utils.ts b/typescript/infra/src/agents/key-utils.ts index 80b2f80da..542ae7aa7 100644 --- a/typescript/infra/src/agents/key-utils.ts +++ b/typescript/infra/src/agents/key-utils.ts @@ -1,4 +1,4 @@ -import { ChainName } from '@hyperlane-xyz/sdk'; +import { ChainName, ProtocolType, chainMetadata } from '@hyperlane-xyz/sdk'; import { Contexts } from '../../config/contexts'; import { @@ -25,8 +25,14 @@ export function getCloudAgentKey( chainName?: ChainName, index?: number, ): CloudAgentKey { - if (agentConfig.aws && role !== Role.Deployer) { - // The deployer is always GCP-based + let isAws = !!agentConfig.aws; + // The deployer is always GCP-based + isAws = isAws && role !== Role.Deployer; + const isSealevel = + !!chainName && chainMetadata[chainName].protocol === ProtocolType.Sealevel; + // Sealevel chains should use GCP-based hex keys for relayers + isAws = isAws && !(isSealevel && role == Role.Relayer); + if (isAws) { return new AgentAwsKey(agentConfig, role, chainName, index); } else { return new AgentGCPKey( diff --git a/typescript/infra/src/config/agent/relayer.ts b/typescript/infra/src/config/agent/relayer.ts index f082ec9f8..40e86ad1c 100644 --- a/typescript/infra/src/config/agent/relayer.ts +++ b/typescript/infra/src/config/agent/relayer.ts @@ -1,6 +1,6 @@ import { BigNumberish } from 'ethers'; -import { ChainMap, chainMetadata } from '@hyperlane-xyz/sdk'; +import { ChainMap, ProtocolType, chainMetadata } from '@hyperlane-xyz/sdk'; import { AgentAwsUser } from '../../agents/aws'; import { Role } from '../../roles'; @@ -125,22 +125,31 @@ export class RelayerConfigHelper extends AgentConfigHelper { // Get the signer configuration for each chain by the chain name. async signers(): Promise> { - if (!this.aws) + if (this.aws) { + const awsUser = new AgentAwsUser( + this.runEnv, + this.context, + Role.Relayer, + this.aws.region, + ); + await awsUser.createIfNotExists(); + const awsKey = (await awsUser.createKeyIfNotExists(this)).keyConfig; + return Object.fromEntries( + this.contextChainNames.map((name) => { + const chain = chainMetadata[name]; + // Sealevel chains always use hex keys + if (chain?.protocol == ProtocolType.Sealevel) { + return [name, { type: KeyType.Hex }]; + } else { + return [name, awsKey]; + } + }), + ); + } else { return Object.fromEntries( this.contextChainNames.map((name) => [name, { type: KeyType.Hex }]), ); - - const awsUser = new AgentAwsUser( - this.runEnv, - this.context, - Role.Relayer, - this.aws.region, - ); - await awsUser.createIfNotExists(); - const key = (await awsUser.createKeyIfNotExists(this)).keyConfig; - return Object.fromEntries( - this.contextChainNames.map((name) => [name, key]), - ); + } } // Returns whether the relayer requires AWS credentials diff --git a/typescript/sdk/src/agents/types.ts b/typescript/sdk/src/agents/types.ts index 8c0fb2757..b0b052f23 100644 --- a/typescript/sdk/src/agents/types.ts +++ b/typescript/sdk/src/agents/types.ts @@ -1,5 +1,6 @@ import { types } from '@hyperlane-xyz/utils'; +import { ProtocolType } from '../consts/chainMetadata'; import { MultiProvider } from '../providers/MultiProvider'; import { ChainMap, ChainName } from '../types'; @@ -30,18 +31,13 @@ export interface HyperlaneAgentAddresses { validatorAnnounce: types.Address; } -export enum AgentProtocol { - Ethereum = 'ethereum', - Fuel = 'fuel', -} - export interface AgentChainSetupBase { name: ChainName; domain: number; signer?: AgentSigner; finalityBlocks: number; addresses: HyperlaneAgentAddresses; - protocol: AgentProtocol; + protocol: ProtocolType; connection?: AgentConnection; index?: { from: number }; } @@ -79,7 +75,7 @@ export function buildAgentConfig( interchainGasPaymaster: addresses[chain].interchainGasPaymaster, validatorAnnounce: addresses[chain].validatorAnnounce, }, - protocol: AgentProtocol.Ethereum, + protocol: metadata.protocol, finalityBlocks: metadata.blocks?.reorgPeriod ?? 1, }; diff --git a/typescript/sdk/src/consts/chainMetadata.test.ts b/typescript/sdk/src/consts/chainMetadata.test.ts index d831310c8..3eba8e41d 100644 --- a/typescript/sdk/src/consts/chainMetadata.test.ts +++ b/typescript/sdk/src/consts/chainMetadata.test.ts @@ -1,10 +1,15 @@ import { expect } from 'chai'; -import { ChainMetadata, isValidChainMetadata } from './chainMetadata'; +import { + ChainMetadata, + ProtocolType, + isValidChainMetadata, +} from './chainMetadata'; const minimalSchema: ChainMetadata = { chainId: 5, name: 'goerli', + protocol: ProtocolType.Ethereum, publicRpcUrls: [{ http: 'https://foobar.com' }], }; diff --git a/typescript/sdk/src/consts/chainMetadata.ts b/typescript/sdk/src/consts/chainMetadata.ts index a1299eb81..cf5e3c824 100644 --- a/typescript/sdk/src/consts/chainMetadata.ts +++ b/typescript/sdk/src/consts/chainMetadata.ts @@ -17,6 +17,12 @@ export enum ExplorerFamily { Other = 'other', } +export enum ProtocolType { + Ethereum = 'ethereum', + Sealevel = 'sealevel', + Fuel = 'fuel', +} + export type ExplorerFamilyType = `${ExplorerFamily}`; /** @@ -28,6 +34,7 @@ export interface ChainMetadata { /** Hyperlane domain, only required if differs from id above */ domainId?: number; name: ChainName; + protocol: ProtocolType; /** Human-readable name */ displayName?: string; /** Shorter human-readable name */ @@ -91,6 +98,7 @@ export const ChainMetadataSchema = z.object({ chainId: z.number().positive(), domainId: z.number().positive().optional(), name: z.string(), + protocol: z.string(), displayName: z.string().optional(), displayNameShort: z.string().optional(), nativeToken: z @@ -174,6 +182,7 @@ export const xDaiToken = { name: 'xDai', symbol: 'xDai', decimals: 18 }; export const alfajores: ChainMetadata = { chainId: 44787, name: Chains.alfajores, + protocol: ProtocolType.Ethereum, displayName: 'Alfajores', nativeToken: celoToken, publicRpcUrls: [{ http: 'https://alfajores-forno.celo-testnet.org' }], @@ -202,6 +211,7 @@ export const alfajores: ChainMetadata = { export const arbitrum: ChainMetadata = { chainId: 42161, name: Chains.arbitrum, + protocol: ProtocolType.Ethereum, displayName: 'Arbitrum', nativeToken: etherToken, publicRpcUrls: [{ http: 'https://arb1.arbitrum.io/rpc' }], @@ -226,6 +236,7 @@ export const arbitrum: ChainMetadata = { export const arbitrumgoerli: ChainMetadata = { chainId: 421613, name: Chains.arbitrumgoerli, + protocol: ProtocolType.Ethereum, displayName: 'Arbitrum Goerli', displayNameShort: 'Arb. Goerli', nativeToken: etherToken, @@ -249,6 +260,7 @@ export const arbitrumgoerli: ChainMetadata = { export const avalanche: ChainMetadata = { chainId: 43114, name: Chains.avalanche, + protocol: ProtocolType.Ethereum, displayName: 'Avalanche', nativeToken: avaxToken, publicRpcUrls: [ @@ -281,6 +293,7 @@ export const avalanche: ChainMetadata = { export const bsc: ChainMetadata = { chainId: 56, name: Chains.bsc, + protocol: ProtocolType.Ethereum, displayName: 'Binance Smart Chain', displayNameShort: 'Binance', nativeToken: bnbToken, @@ -308,6 +321,7 @@ export const bsc: ChainMetadata = { export const bsctestnet: ChainMetadata = { chainId: 97, name: Chains.bsctestnet, + protocol: ProtocolType.Ethereum, displayName: 'BSC Testnet', nativeToken: bnbToken, publicRpcUrls: [{ http: 'https://data-seed-prebsc-1-s3.binance.org:8545' }], @@ -330,6 +344,7 @@ export const bsctestnet: ChainMetadata = { export const celo: ChainMetadata = { chainId: 42220, name: Chains.celo, + protocol: ProtocolType.Ethereum, displayName: 'Celo', nativeToken: celoToken, publicRpcUrls: [{ http: 'https://forno.celo.org' }], @@ -359,6 +374,7 @@ export const celo: ChainMetadata = { export const ethereum: ChainMetadata = { chainId: 1, name: Chains.ethereum, + protocol: ProtocolType.Ethereum, displayName: 'Ethereum', nativeToken: etherToken, publicRpcUrls: [ @@ -390,6 +406,7 @@ export const ethereum: ChainMetadata = { export const fuji: ChainMetadata = { chainId: 43113, name: Chains.fuji, + protocol: ProtocolType.Ethereum, displayName: 'Fuji', nativeToken: avaxToken, publicRpcUrls: [ @@ -417,6 +434,7 @@ export const fuji: ChainMetadata = { export const goerli: ChainMetadata = { chainId: 5, name: Chains.goerli, + protocol: ProtocolType.Ethereum, displayName: 'Goerli', nativeToken: etherToken, publicRpcUrls: [ @@ -443,6 +461,7 @@ export const goerli: ChainMetadata = { export const sepolia: ChainMetadata = { chainId: 11155111, name: Chains.sepolia, + protocol: ProtocolType.Ethereum, displayName: 'Sepolia', nativeToken: etherToken, publicRpcUrls: [ @@ -468,6 +487,7 @@ export const sepolia: ChainMetadata = { export const moonbasealpha: ChainMetadata = { chainId: 1287, name: Chains.moonbasealpha, + protocol: ProtocolType.Ethereum, displayName: 'Moonbase Alpha', displayNameShort: 'Moonbase', nativeToken: { @@ -495,6 +515,7 @@ export const moonbasealpha: ChainMetadata = { export const moonbeam: ChainMetadata = { chainId: 1284, name: Chains.moonbeam, + protocol: ProtocolType.Ethereum, displayName: 'Moonbeam', nativeToken: { decimals: 18, @@ -522,6 +543,7 @@ export const moonbeam: ChainMetadata = { export const mumbai: ChainMetadata = { chainId: 80001, name: Chains.mumbai, + protocol: ProtocolType.Ethereum, displayName: 'Mumbai', nativeToken: maticToken, publicRpcUrls: [ @@ -556,6 +578,7 @@ export const mumbai: ChainMetadata = { export const optimism: ChainMetadata = { chainId: 10, name: Chains.optimism, + protocol: ProtocolType.Ethereum, displayName: 'Optimism', nativeToken: etherToken, publicRpcUrls: [{ http: 'https://mainnet.optimism.io' }], @@ -580,6 +603,7 @@ export const optimism: ChainMetadata = { export const optimismgoerli: ChainMetadata = { chainId: 420, name: Chains.optimismgoerli, + protocol: ProtocolType.Ethereum, displayName: 'Optimism Goerli', displayNameShort: 'Opt. Goerli', nativeToken: etherToken, @@ -603,6 +627,7 @@ export const optimismgoerli: ChainMetadata = { export const polygon: ChainMetadata = { chainId: 137, name: Chains.polygon, + protocol: ProtocolType.Ethereum, displayName: 'Polygon', nativeToken: etherToken, publicRpcUrls: [ @@ -637,6 +662,7 @@ export const polygon: ChainMetadata = { export const gnosis: ChainMetadata = { chainId: 100, name: Chains.gnosis, + protocol: ProtocolType.Ethereum, displayName: 'Gnosis', nativeToken: xDaiToken, publicRpcUrls: [ @@ -668,6 +694,7 @@ export const gnosis: ChainMetadata = { export const test1: ChainMetadata = { chainId: 13371, name: Chains.test1, + protocol: ProtocolType.Ethereum, displayName: 'Test 1', nativeToken: etherToken, publicRpcUrls: [{ http: 'http://localhost:8545' }], @@ -683,6 +710,7 @@ export const test1: ChainMetadata = { export const test2: ChainMetadata = { chainId: 13372, name: Chains.test2, + protocol: ProtocolType.Ethereum, displayName: 'Test 2', nativeToken: etherToken, publicRpcUrls: [{ http: 'http://localhost:8545' }], @@ -698,6 +726,7 @@ export const test2: ChainMetadata = { export const test3: ChainMetadata = { chainId: 13373, name: Chains.test3, + protocol: ProtocolType.Ethereum, displayName: 'Test 3', nativeToken: etherToken, publicRpcUrls: [{ http: 'http://localhost:8545' }], diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 895e32fac..11a31ca0f 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -13,6 +13,7 @@ export { ChainMetadataSchema, ExplorerFamily, ExplorerFamilyType, + ProtocolType, RpcPaginationOptions, chainIdToMetadata, chainMetadata,