From d24eaa4e323a9f03737180ae75839b75a956cf69 Mon Sep 17 00:00:00 2001 From: Trevor Porter Date: Thu, 28 Jul 2022 13:13:06 +0100 Subject: [PATCH] Fix relayer funder - fix identifier parsing & error logging (#843) * Fix relayer funder by fixing identifier parsing (w/ tests), and ensuring errors are logged * nit * more test keys --- .../funding/fund-relayers-from-deployer.ts | 5 +- typescript/infra/src/agents/agent.ts | 26 ++++----- typescript/infra/test/agents.test.ts | 58 +++++++++++++++++++ 3 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 typescript/infra/test/agents.test.ts diff --git a/typescript/infra/scripts/funding/fund-relayers-from-deployer.ts b/typescript/infra/scripts/funding/fund-relayers-from-deployer.ts index 9c867d873..b539264e0 100644 --- a/typescript/infra/scripts/funding/fund-relayers-from-deployer.ts +++ b/typescript/infra/scripts/funding/fund-relayers-from-deployer.ts @@ -1,6 +1,7 @@ import { Console } from 'console'; import { ethers } from 'ethers'; import { Gauge, Registry } from 'prom-client'; +import { format } from 'util'; import { ChainConnection, CompleteChainMap } from '@abacus-network/sdk'; @@ -247,7 +248,9 @@ function relayerKeyInfo(relayerKey: AgentKey) { main().catch((err) => { error('Error occurred in main', { - error: err, + // JSON.stringifying an Error returns '{}'. + // This is a workaround from https://stackoverflow.com/a/60370781 + error: format(err), }); process.exit(1); }); diff --git a/typescript/infra/src/agents/agent.ts b/typescript/infra/src/agents/agent.ts index 442d0e8f6..d19a17af1 100644 --- a/typescript/infra/src/agents/agent.ts +++ b/typescript/infra/src/agents/agent.ts @@ -69,43 +69,43 @@ export class ReadOnlyAgentKey extends AgentKey { address: string, ): ReadOnlyAgentKey { const regex = - /.*([a-zA-Z0-9]+)-([a-zA-Z0-9]+)-key-([a-zA-Z0-9]+)-?([a-zA-Z0-9]+)?-?([0-9]+)?/g; + /(alias\/)?([a-zA-Z0-9]+)-([a-zA-Z0-9]+)-key-([a-zA-Z0-9]+)-?([a-zA-Z0-9]+)?-?([0-9]+)?/g; const matches = regex.exec(identifier); if (!matches) { throw Error('Invalid identifier'); } - const context = assertContext(matches[1]); - const environment = matches[2]; + const context = assertContext(matches[2]); + const environment = matches[3]; - // If matches[4] is undefined, this key doesn't have a chainName, and matches[3] + // If matches[5] is undefined, this key doesn't have a chainName, and matches[4] // is the role name. - if (matches[4] === undefined) { + if (matches[5] === undefined) { return new ReadOnlyAgentKey( environment, context, - assertRole(matches[3]), + assertRole(matches[4]), identifier, address, ); - } else if (matches[5] === undefined) { - // If matches[5] is undefined, this key doesn't have an index. + } else if (matches[6] === undefined) { + // If matches[6] is undefined, this key doesn't have an index. return new ReadOnlyAgentKey( environment, context, - assertRole(matches[4]), + assertRole(matches[5]), identifier, address, - assertChain(matches[3]), + assertChain(matches[4]), ); } else { return new ReadOnlyAgentKey( environment, context, - assertRole(matches[4]), + assertRole(matches[5]), identifier, address, - assertChain(matches[3]), - parseInt(matches[5]), + assertChain(matches[4]), + parseInt(matches[6]), ); } } diff --git a/typescript/infra/test/agents.test.ts b/typescript/infra/test/agents.test.ts new file mode 100644 index 000000000..a1637de71 --- /dev/null +++ b/typescript/infra/test/agents.test.ts @@ -0,0 +1,58 @@ +import { expect } from 'chai'; + +import { Contexts } from '../config/contexts'; +import { ReadOnlyAgentKey } from '../src/agents/agent'; +import { AgentAwsKey } from '../src/agents/aws'; +import { AgentGCPKey } from '../src/agents/gcp'; +import { KEY_ROLE_ENUM } from '../src/agents/roles'; + +describe('ReadOnlyAgentKey', () => { + describe('fromSerializedAddress', () => { + it('correctly parses identifiers', () => { + const addressZero = '0x0000000000000000000000000000000000000000'; + const environment = 'test'; + const context = Contexts.Abacus; + const chainName = 'test1'; + // Enough to satisfy the constructor of AgentAwsKey + const mockAgentConfig: any = { + aws: { + region: 'us-east-1', + }, + environment, + context, + }; + + // AWS and GCP agent keys to get the identifiers from + // and ensure they can be correctly parsed + const testKeys = [ + new AgentGCPKey(environment, context, KEY_ROLE_ENUM.Deployer), + new AgentGCPKey(environment, context, KEY_ROLE_ENUM.Relayer, chainName), + new AgentGCPKey( + environment, + context, + KEY_ROLE_ENUM.Validator, + chainName, + 0, + ), + new AgentAwsKey(mockAgentConfig, KEY_ROLE_ENUM.Deployer), + new AgentAwsKey(mockAgentConfig, KEY_ROLE_ENUM.Relayer, chainName), + new AgentAwsKey(mockAgentConfig, KEY_ROLE_ENUM.Validator, chainName, 0), + ]; + + for (const testKey of testKeys) { + const identifier = testKey.identifier; + + const readOnly = ReadOnlyAgentKey.fromSerializedAddress( + identifier, + addressZero, + ); + + expect(readOnly.environment).to.eq(testKey.environment); + expect(readOnly.context).to.eq(testKey.context); + expect(readOnly.role).to.eq(testKey.role); + expect(readOnly.chainName).to.eq(testKey.chainName); + expect(readOnly.index).to.eq(testKey.index); + } + }); + }); +});