Fixed key funder (#1725)

* key funder fixes

* Minor tweaks

* Updated configs

* Update funding to deploy to rc

* Deploy

* Better error handling

* Don't include empty addresses and log errors

* Deploy kathy to rc

* Deploy key funder
pull/1730/head
Mattie Conover 2 years ago committed by GitHub
parent 7eb61ab036
commit 65ff5528ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      typescript/infra/config/environments/mainnet2/funding.ts
  2. 2
      typescript/infra/config/environments/mainnet2/helloworld.ts
  3. 4
      typescript/infra/config/environments/testnet3/funding.ts
  4. 2
      typescript/infra/config/environments/testnet3/helloworld.ts
  5. 30
      typescript/infra/scripts/funding/fund-keys-from-deployer.ts
  6. 33
      typescript/infra/scripts/get-key-addresses.ts
  7. 20
      typescript/infra/src/utils/metrics.ts

@ -8,13 +8,12 @@ import { environment } from './chains';
export const keyFunderConfig: KeyFunderConfig = { export const keyFunderConfig: KeyFunderConfig = {
docker: { docker: {
repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo',
// TODO: Use an image built off of main tag: 'sha-3ff9c8b',
tag: 'sha-d1ad862',
}, },
// We're currently using the same deployer key as mainnet. // We're currently using the same deployer key as mainnet.
// To minimize nonce clobbering we offset the key funder cron // To minimize nonce clobbering we offset the key funder cron
// schedule by 30 minutes. // schedule by 30 minutes.
cronSchedule: '15 * * * *', // Every hour at the 15 minute mark cronSchedule: '15 * * * *', // Every hour at the 15-minute mark
namespace: environment, namespace: environment,
prometheusPushGateway: prometheusPushGateway:
'http://prometheus-pushgateway.monitoring.svc.cluster.local:9091', 'http://prometheus-pushgateway.monitoring.svc.cluster.local:9091',

@ -33,7 +33,7 @@ export const releaseCandidate: HelloWorldConfig<MainnetChains> = {
kathy: { kathy: {
docker: { docker: {
repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo',
tag: 'sha-0477ee1', tag: 'sha-19dc142',
}, },
chainsToSkip: [], chainsToSkip: [],
runEnv: environment, runEnv: environment,

@ -8,12 +8,12 @@ import { environment } from './chains';
export const keyFunderConfig: KeyFunderConfig = { export const keyFunderConfig: KeyFunderConfig = {
docker: { docker: {
repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo',
tag: 'sha-6ee34e4', tag: 'sha-3ff9c8b',
}, },
// We're currently using the same deployer key as testnet2. // We're currently using the same deployer key as testnet2.
// To minimize nonce clobbering we offset the key funder cron // To minimize nonce clobbering we offset the key funder cron
// schedule by 30 minutes. // schedule by 30 minutes.
cronSchedule: '15 * * * *', // Every hour at the 15 minute mark cronSchedule: '15 * * * *', // Every hour at the 15-minute mark
namespace: environment, namespace: environment,
prometheusPushGateway: prometheusPushGateway:
'http://prometheus-pushgateway.monitoring.svc.cluster.local:9091', 'http://prometheus-pushgateway.monitoring.svc.cluster.local:9091',

@ -32,7 +32,7 @@ export const releaseCandidate: HelloWorldConfig<TestnetChains> = {
kathy: { kathy: {
docker: { docker: {
repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', repo: 'gcr.io/abacus-labs-dev/hyperlane-monorepo',
tag: 'sha-0477ee1', tag: 'sha-6ee34e4',
}, },
chainsToSkip: [], chainsToSkip: [],
runEnv: environment, runEnv: environment,

@ -177,7 +177,6 @@ async function main() {
), ),
); );
} else { } else {
contextFunders = [];
const contexts = Object.keys(argv.contextsAndRoles) as Contexts[]; const contexts = Object.keys(argv.contextsAndRoles) as Contexts[];
contextFunders = await Promise.all( contextFunders = await Promise.all(
contexts.map((context) => contexts.map((context) =>
@ -192,10 +191,7 @@ async function main() {
let failureOccurred = false; let failureOccurred = false;
for (const funder of contextFunders) { for (const funder of contextFunders) {
const failure = await funder.fund(); failureOccurred ||= await funder.fund();
if (failure) {
failureOccurred = true;
}
} }
await submitMetrics(metricsRegister, 'key-funder'); await submitMetrics(metricsRegister, 'key-funder');
@ -296,18 +292,25 @@ class ContextFunder {
async fund(): Promise<boolean> { async fund(): Promise<boolean> {
let failureOccurred = false; let failureOccurred = false;
const chainKeys = this.getChainKeys(); const promises = Object.entries(this.getChainKeys()).map(
await Promise.all( async ([chain, keys]) => {
Object.entries(chainKeys).map(async ([chain, keys]) => {
if (keys.length > 0) { if (keys.length > 0) {
await this.bridgeIfL2(chain as ChainName); await this.bridgeIfL2(chain as ChainName);
} }
keys.forEach(async (key) => { for (const key of keys) {
const failure = await this.attemptToFundKey(key, chain as ChainName); const failure = await this.attemptToFundKey(key, chain as ChainName);
failureOccurred = failureOccurred || failure; failureOccurred ||= failure;
}); }
}), },
); );
try {
await Promise.all(promises);
} catch (e) {
error('Unhandled error when funding key', { error: format(e) });
failureOccurred = true;
}
return failureOccurred; return failureOccurred;
} }
@ -381,7 +384,6 @@ class ContextFunder {
// on L1 gas. // on L1 gas.
const bridgeAmount = await this.getFundingAmount( const bridgeAmount = await this.getFundingAmount(
chainConnection, chainConnection,
chain,
funderAddress, funderAddress,
desiredBalanceEther.mul(10), desiredBalanceEther.mul(10),
); );
@ -393,7 +395,6 @@ class ContextFunder {
private async getFundingAmount( private async getFundingAmount(
chainConnection: ChainConnection, chainConnection: ChainConnection,
chain: ChainName,
address: string, address: string,
desiredBalance: BigNumber, desiredBalance: BigNumber,
): Promise<BigNumber> { ): Promise<BigNumber> {
@ -419,7 +420,6 @@ class ContextFunder {
); );
const fundingAmount = await this.getFundingAmount( const fundingAmount = await this.getFundingAmount(
chainConnection, chainConnection,
chain,
key.address, key.address,
desiredBalanceEther, desiredBalanceEther,
); );

@ -6,23 +6,24 @@ async function main() {
const agentConfig = await getContextAgentConfig(); const agentConfig = await getContextAgentConfig();
const keys = getAllCloudAgentKeys(agentConfig); const keys = getAllCloudAgentKeys(agentConfig);
const keyInfoPromises = keys.map(async (key) => {
const keyInfos = await Promise.all( let address = '';
keys.map(async (key) => { try {
let address = ''; await key.fetch();
try { address = key.address;
await key.fetch(); } catch (e) {
address = key.address; // Swallow error
} catch (e) { console.error('Error getting address', { key: key.identifier });
// Swallow error }
} return {
return { identifier: key.identifier,
identifier: key.identifier, address,
address, };
}; });
}), const keyInfos = (await Promise.all(keyInfoPromises)).filter(
// remove any keys we could not get an address for
({ address }) => !!address,
); );
console.log(JSON.stringify(keyInfos, null, 2)); console.log(JSON.stringify(keyInfos, null, 2));
} }

@ -1,5 +1,8 @@
import http from 'http'; import http from 'http';
import { Pushgateway, Registry } from 'prom-client'; import { Pushgateway, Registry } from 'prom-client';
import { format } from 'util';
import { error, log } from '@hyperlane-xyz/utils';
function getPushGateway(register: Registry): Pushgateway | null { function getPushGateway(register: Registry): Pushgateway | null {
const gatewayAddr = process.env['PROMETHEUS_PUSH_GATEWAY']; const gatewayAddr = process.env['PROMETHEUS_PUSH_GATEWAY'];
@ -22,19 +25,22 @@ export async function submitMetrics(
if (!gateway) return; if (!gateway) return;
let resp; let resp;
if (options?.appendMode) { try {
resp = (await gateway.pushAdd({ jobName })).resp; if (options?.appendMode) {
} else { resp = (await gateway.pushAdd({ jobName })).resp;
resp = (await gateway.push({ jobName })).resp; } else {
resp = (await gateway.push({ jobName })).resp;
}
} catch (e) {
error('Error when pushing metrics', { error: format(e) });
return;
} }
const statusCode = const statusCode =
typeof resp == 'object' && resp != null && 'statusCode' in resp typeof resp == 'object' && resp != null && 'statusCode' in resp
? (resp as any).statusCode ? (resp as any).statusCode
: 'unknown'; : 'unknown';
console.log( log('Prometheus metrics pushed to PushGateway', { statusCode });
`Prometheus metrics pushed to PushGateway with status ${statusCode}`,
);
} }
/** /**

Loading…
Cancel
Save