From 68f7deec0601afb513fb483d3ca12d386a49b908 Mon Sep 17 00:00:00 2001 From: Paul Balaji Date: Mon, 19 Feb 2024 16:09:24 +0000 Subject: [PATCH] feat: move desired balances into KeyFunderConfig + bump thresholds (#3284) --- solidity/foundry.toml | 2 +- .../config/environments/mainnet3/funding.ts | 33 ++++++ .../config/environments/testnet4/funding.ts | 19 ++- .../helm/key-funder/templates/cron-job.yaml | 10 +- .../funding/fund-keys-from-deployer.ts | 108 +++++++++--------- typescript/infra/src/config/funding.ts | 4 +- typescript/infra/src/funding/key-funder.ts | 2 + 7 files changed, 118 insertions(+), 60 deletions(-) diff --git a/solidity/foundry.toml b/solidity/foundry.toml index 7de8898d167..5f3db3949ed 100644 --- a/solidity/foundry.toml +++ b/solidity/foundry.toml @@ -15,4 +15,4 @@ verbosity = 4 [rpc_endpoints] mainnet = "https://eth.merkle.io" -optimism = "https://optimism.llamarpc.com" +optimism = "https://mainnet.optimism.io " diff --git a/typescript/infra/config/environments/mainnet3/funding.ts b/typescript/infra/config/environments/mainnet3/funding.ts index a2b8ec6a5f1..f90b68503f1 100644 --- a/typescript/infra/config/environments/mainnet3/funding.ts +++ b/typescript/infra/config/environments/mainnet3/funding.ts @@ -24,4 +24,37 @@ export const keyFunderConfig: KeyFunderConfig = { [Contexts.ReleaseCandidate]: [Role.Relayer, Role.Kathy], }, connectionType: RpcConsensusType.Single, + // desired balance config + desiredBalancePerChain: { + arbitrum: '3', + avalanche: '5', + base: '3', + bsc: '5', + celo: '3', + ethereum: '5', + gnosis: '5', + inevm: '3', + moonbeam: '5', + optimism: '3', + polygon: '20', + polygonzkevm: '3', + scroll: '3', + viction: '3', + }, + desiredKathyBalancePerChain: { + arbitrum: '0.1', + avalanche: '6', + base: '0.05', + bsc: '0.35', + celo: '150', + ethereum: '0.4', + gnosis: '100', + inevm: '0.05', + moonbeam: '250', + optimism: '0.1', + polygon: '85', + polygonzkevm: '0.05', + scroll: '0.05', + viction: '0.05', + }, }; diff --git a/typescript/infra/config/environments/testnet4/funding.ts b/typescript/infra/config/environments/testnet4/funding.ts index b61cbc424dc..f0a7a016381 100644 --- a/typescript/infra/config/environments/testnet4/funding.ts +++ b/typescript/infra/config/environments/testnet4/funding.ts @@ -9,7 +9,7 @@ import { environment } from './chains'; export const keyFunderConfig: KeyFunderConfig = { docker: { repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', - tag: '620925c-20240213-171901', + tag: '8507211-20240219-124301', }, // We're currently using the same deployer key as testnet2. // To minimize nonce clobbering we offset the key funder cron @@ -24,4 +24,21 @@ export const keyFunderConfig: KeyFunderConfig = { [Contexts.ReleaseCandidate]: [Role.Relayer, Role.Kathy], }, connectionType: RpcConsensusType.Quorum, + // desired balance config + desiredBalancePerChain: { + alfajores: '5', + arbitrumgoerli: '0.5', + bsctestnet: '5', + fuji: '5', + goerli: '0.5', + mumbai: '5', + optimismgoerli: '0.5', + plumetestnet: '0.2', + polygonzkevmtestnet: '1', + scrollsepolia: '1', + sepolia: '5', + }, + desiredKathyBalancePerChain: { + plumetestnet: '0.05', + }, }; diff --git a/typescript/infra/helm/key-funder/templates/cron-job.yaml b/typescript/infra/helm/key-funder/templates/cron-job.yaml index a1ac085f85a..d51f0791849 100644 --- a/typescript/infra/helm/key-funder/templates/cron-job.yaml +++ b/typescript/infra/helm/key-funder/templates/cron-job.yaml @@ -32,6 +32,14 @@ spec: {{- if .Values.hyperlane.connectionType }} - --connection-type - {{ .Values.hyperlane.connectionType }} +{{- end }} +{{- range $chain, $balance := .Values.hyperlane.desiredBalancePerChain }} + - --desired-balance-per-chain + - {{ $chain }}={{ $balance }} +{{- end }} +{{- range $chain, $balance := .Values.hyperlane.desiredKathyBalancePerChain }} + - --desired-kathy-balance-per-chain + - {{ $chain }}={{ $balance }} {{- end }} env: - name: PROMETHEUS_PUSH_GATEWAY @@ -46,4 +54,4 @@ spec: - name: key-funder-addresses-secret secret: secretName: key-funder-addresses-secret - defaultMode: 0400 \ No newline at end of file + defaultMode: 0400 diff --git a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts index d4feedeef99..ee4c2da3d5c 100644 --- a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts +++ b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts @@ -33,7 +33,11 @@ import { } from '../../src/agents/keys'; import { DeployEnvironment } from '../../src/config'; import { deployEnvToSdkEnv } from '../../src/config/environment'; -import { ContextAndRoles, ContextAndRolesMap } from '../../src/config/funding'; +import { + ContextAndRoles, + ContextAndRolesMap, + KeyFunderConfig, +} from '../../src/config/funding'; import { FundableRole, Role } from '../../src/roles'; import { submitMetrics } from '../../src/utils/metrics'; import { @@ -122,57 +126,6 @@ const MIN_DELTA_DENOMINATOR = ethers.BigNumber.from(10); const RC_FUNDING_DISCOUNT_NUMERATOR = ethers.BigNumber.from(2); const RC_FUNDING_DISCOUNT_DENOMINATOR = ethers.BigNumber.from(10); -const desiredBalancePerChain: ChainMap = { - celo: '0.3', - alfajores: '1', - avalanche: '3', - fuji: '1', - ethereum: '0.5', - polygon: '2', - mumbai: '0.8', - optimism: '0.5', - arbitrum: '0.5', - bsc: '0.05', - bsctestnet: '1', - goerli: '0.5', - sepolia: '0.5', - moonbeam: '0.5', - optimismgoerli: '0.5', - arbitrumgoerli: '0.5', - gnosis: '0.1', - scrollsepolia: '0.05', - polygonzkevm: '0.3', - scroll: '0.3', - base: '0.3', - polygonzkevmtestnet: '0.3', - plumetestnet: '0.2', - - // unused - test1: '0', - test2: '0', - test3: '0', -}; - -// Used to fund kathy with more tokens such that it's able to pay interchain gas -// on mainnet. The amount is roughly > $100 -const desiredKathyBalancePerChain: ChainMap = { - celo: '150', - avalanche: '6', - polygon: '85', - ethereum: '0.4', - optimism: '0.1', - arbitrum: '0.1', - bsc: '0.35', - moonbeam: '250', - gnosis: '100', - scroll: '0.05', - base: '0.05', - polygonzkevm: '0.05', - viction: '0.05', - inevm: '0.05', - plumetestnet: '0.05', -}; - // The balance threshold of the IGP contract that must be met for the key funder // to call `claim()` const igpClaimThresholdPerChain: ChainMap = { @@ -239,6 +192,23 @@ async function main() { .coerce('contexts-and-roles', parseContextAndRolesMap) .demandOption('contexts-and-roles') + .string('desired-balance-per-chain') + .array('desired-balance-per-chain') + .describe( + 'desired-balance-per-chain', + 'Array indicating target balance to fund for each chain. Each element is expected as =', + ) + .coerce('desired-balance-per-chain', parseBalancePerChain) + .demandOption('desired-balance-per-chain') + + .string('desired-kathy-balance-per-chain') + .array('desired-kathy-balance-per-chain') + .describe( + 'desired-kathy-balance-per-chain', + 'Array indicating target balance to fund Kathy for each chain. Each element is expected as =', + ) + .coerce('desired-kathy-balance-per-chain', parseBalancePerChain) + .string('connection-type') .describe('connection-type', 'The provider connection type to use for RPCs') .default('connection-type', RpcConsensusType.Single) @@ -269,6 +239,8 @@ async function main() { multiProvider, argv.contextsAndRoles, argv.skipIgpClaim, + argv.desiredBalancePerChain, + argv.desiredKathyBalancePerChain ?? {}, path, ), ); @@ -282,6 +254,8 @@ async function main() { context, argv.contextsAndRoles[context]!, argv.skipIgpClaim, + argv.desiredBalancePerChain, + argv.desiredKathyBalancePerChain ?? {}, ), ), ); @@ -313,6 +287,8 @@ class ContextFunder { public readonly context: Contexts, public readonly rolesToFund: FundableRole[], public readonly skipIgpClaim: boolean, + public readonly desiredBalancePerChain: KeyFunderConfig['desiredBalancePerChain'], + public readonly desiredKathyBalancePerChain: KeyFunderConfig['desiredKathyBalancePerChain'], ) { // At the moment, only blessed EVM chains are supported roleKeysPerChain = objFilter( @@ -350,6 +326,8 @@ class ContextFunder { multiProvider: MultiProvider, contextsAndRolesToFund: ContextAndRolesMap, skipIgpClaim: boolean, + desiredBalancePerChain: KeyFunderConfig['desiredBalancePerChain'], + desiredKathyBalancePerChain: KeyFunderConfig['desiredKathyBalancePerChain'], filePath: string, ) { log('Reading identifiers and addresses from file', { @@ -415,6 +393,8 @@ class ContextFunder { context, contextsAndRolesToFund[context]!, skipIgpClaim, + desiredBalancePerChain, + desiredKathyBalancePerChain, ); } @@ -425,6 +405,8 @@ class ContextFunder { context: Contexts, rolesToFund: FundableRole[], skipIgpClaim: boolean, + desiredBalancePerChain: KeyFunderConfig['desiredBalancePerChain'], + desiredKathyBalancePerChain: KeyFunderConfig['desiredKathyBalancePerChain'], ) { // only roles that are fundable keys ie. relayer and kathy const fundableRoleKeys: Record = { @@ -468,6 +450,8 @@ class ContextFunder { context, rolesToFund, skipIgpClaim, + desiredBalancePerChain, + desiredKathyBalancePerChain, ); } @@ -558,7 +542,7 @@ class ContextFunder { if (L2Chains.includes(chain)) { const funderAddress = await this.multiProvider.getSignerAddress(chain)!; const desiredBalanceEther = ethers.utils.parseUnits( - desiredBalancePerChain[chain], + this.desiredBalancePerChain[chain], 'ether', ); // Optionally bridge ETH to L2 before funding the desired key. @@ -625,9 +609,9 @@ class ContextFunder { private getDesiredBalanceForRole(chain: ChainName, role: Role): BigNumber { const desiredBalanceEther = - role === Role.Kathy && desiredKathyBalancePerChain[chain] - ? desiredKathyBalancePerChain[chain] - : desiredBalancePerChain[chain]; + role === Role.Kathy && this.desiredKathyBalancePerChain[chain] + ? this.desiredKathyBalancePerChain[chain] + : this.desiredBalancePerChain[chain]; let desiredBalance = ethers.utils.parseEther(desiredBalanceEther ?? '0'); if (this.context === Contexts.ReleaseCandidate) { desiredBalance = desiredBalance @@ -910,6 +894,18 @@ function parseContextAndRoles(str: string): ContextAndRoles { }; } +function parseBalancePerChain(strs: string[]): ChainMap { + const balanceMap: ChainMap = {}; + strs.forEach((str) => { + const [chain, balance] = str.split('='); + if (!chain || !balance) { + throw new Error(`Invalid format for balance entry: ${str}`); + } + balanceMap[chain] = balance; + }); + return balanceMap; +} + // Returns whether an error occurred async function gracefullyHandleError( fn: () => Promise, diff --git a/typescript/infra/src/config/funding.ts b/typescript/infra/src/config/funding.ts index 89d35f54a6d..c0834abc4bd 100644 --- a/typescript/infra/src/config/funding.ts +++ b/typescript/infra/src/config/funding.ts @@ -1,4 +1,4 @@ -import { RpcConsensusType } from '@hyperlane-xyz/sdk'; +import { ChainMap, RpcConsensusType } from '@hyperlane-xyz/sdk'; import { Contexts } from '../../config/contexts'; import { FundableRole, Role } from '../roles'; @@ -21,4 +21,6 @@ export interface KeyFunderConfig { cyclesBetweenEthereumMessages?: number; prometheusPushGateway: string; connectionType: RpcConsensusType.Single | RpcConsensusType.Quorum; + desiredBalancePerChain: ChainMap; + desiredKathyBalancePerChain: ChainMap; } diff --git a/typescript/infra/src/funding/key-funder.ts b/typescript/infra/src/funding/key-funder.ts index 142d323be61..78f58e55315 100644 --- a/typescript/infra/src/funding/key-funder.ts +++ b/typescript/infra/src/funding/key-funder.ts @@ -48,6 +48,8 @@ function getKeyFunderHelmValues( contextFundingFrom: keyFunderConfig.contextFundingFrom, contextsAndRolesToFund: keyFunderConfig.contextsAndRolesToFund, connectionType: keyFunderConfig.connectionType, + desiredBalancePerChain: keyFunderConfig.desiredBalancePerChain, + desiredKathyBalancePerChain: keyFunderConfig.desiredKathyBalancePerChain, }, image: { repository: keyFunderConfig.docker.repo,