From 9ebd98f397416e89194450c83cc08a4367c469d1 Mon Sep 17 00:00:00 2001 From: Felipe Andrade Date: Thu, 9 Nov 2023 13:29:17 -0800 Subject: [PATCH] feat: multisig-mon --- packages/chain-mon/.env.example | 12 ++ packages/chain-mon/package.json | 10 +- packages/chain-mon/src/balance-mon/service.ts | 42 +------ packages/chain-mon/src/index.ts | 3 +- .../chain-mon/src/multisig-mon/service.ts | 109 ++++++++++++++++++ 5 files changed, 130 insertions(+), 46 deletions(-) create mode 100644 packages/chain-mon/src/multisig-mon/service.ts diff --git a/packages/chain-mon/.env.example b/packages/chain-mon/.env.example index 3e952b04ca071..aa343b7200a72 100644 --- a/packages/chain-mon/.env.example +++ b/packages/chain-mon/.env.example @@ -8,6 +8,18 @@ BALANCE_MON__RPC= # JSON array in the format [{ "address":
, "nickname": }, ... ] BALANCE_MON__ACCOUNTS= + +############################################################################### +# ↓ multisig-mon ↓ # +############################################################################### + +# RPC pointing to network to monitor balances on +MULTISIG_MON__RPC= + +# JSON array in the format [{ "address":
, "nickname": }, ... ] +MULTISIG_MON__ACCOUNTS= + + ############################################################################### # ↓ wallet-mon ↓ # ############################################################################### diff --git a/packages/chain-mon/package.json b/packages/chain-mon/package.json index 19abaad32b49c..fe2ecaa782628 100644 --- a/packages/chain-mon/package.json +++ b/packages/chain-mon/package.json @@ -10,17 +10,19 @@ ], "scripts": { "dev:balance-mon": "tsx watch ./src/balance-mon/service.ts", - "dev:wallet-mon": "tsx watch ./src/wallet-mon/service.ts", "dev:drippie-mon": "tsx watch ./src/drippie-mon/service.ts", - "dev:wd-mon": "tsx watch ./src/wd-mon/service.ts", "dev:fault-mon": "tsx watch ./src/fault-mon/service.ts", "dev:replica-mon": "tsx watch ./src/replica-mon/service.ts", + "dev:wallet-mon": "tsx watch ./src/wallet-mon/service.ts", + "dev:wd-mon": "tsx watch ./src/wd-mon/service.ts", + "start:balance-mon": "tsx ./src/balance-mon/service.ts", - "start:wallet-mon": "tsx ./src/wallet-mon/service.ts", "start:drippie-mon": "tsx ./src/drippie-mon/service.ts", - "start:wd-mon": "tsx ./src/wd-mon/service.ts", "start:fault-mon": "tsx ./src/fault-mon/service.ts", "start:replica-mon": "tsx ./src/replica-mon/service.ts", + "start:wallet-mon": "tsx ./src/wallet-mon/service.ts", + "start:wd-mon": "tsx ./src/wd-mon/service.ts", + "test": "hardhat test", "test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json", "build": "tsc -p ./tsconfig.json", diff --git a/packages/chain-mon/src/balance-mon/service.ts b/packages/chain-mon/src/balance-mon/service.ts index 392dbc7696afa..3382fc8bc8bb4 100644 --- a/packages/chain-mon/src/balance-mon/service.ts +++ b/packages/chain-mon/src/balance-mon/service.ts @@ -6,9 +6,7 @@ import { validators, } from '@eth-optimism/common-ts' import { Provider } from '@ethersproject/abstract-provider' -import { BigNumber, ethers } from 'ethers' -import Safe from '../abi/IGnosisSafe.0.8.19.json' import { version } from '../../package.json' type BalanceMonOptions = { @@ -18,12 +16,11 @@ type BalanceMonOptions = { type BalanceMonMetrics = { balances: Gauge - safeNonces: Gauge unexpectedRpcErrors: Counter } type BalanceMonState = { - accounts: Array<{ address: string; nickname: string; safe: boolean }> + accounts: Array<{ address: string; nickname: string }> } export class BalanceMonService extends BaseServiceV2< @@ -57,11 +54,6 @@ export class BalanceMonService extends BaseServiceV2< desc: 'Balances of addresses', labels: ['address', 'nickname'], }, - safeNonces: { - type: Gauge, - desc: 'Safe nonce', - labels: ['address', 'nickname'], - }, unexpectedRpcErrors: { type: Counter, desc: 'Number of unexpected RPC errors', @@ -103,38 +95,6 @@ export class BalanceMonService extends BaseServiceV2< name: 'getBalance', }) } - - // Get the safe nonce to report - if (account.safe) { - try { - const safeContract = new ethers.Contract( - account.address, - Safe.abi, - this.options.rpc - ) - const safeNonce = BigNumber.from(await safeContract.nonce()) - this.logger.info(`got nonce`, { - address: account.address, - nickname: account.nickname, - nonce: safeNonce.toString(), - }) - - this.metrics.safeNonces.set( - { address: account.address, nickname: account.nickname }, - parseInt(safeNonce.toString(), 10) - ) - } catch (err) { - this.logger.info(`got unexpected RPC error`, { - section: 'safeNonce', - name: 'getSafeNonce', - err, - }) - this.metrics.unexpectedRpcErrors.inc({ - section: 'safeNonce', - name: 'getSafeNonce', - }) - } - } } } } diff --git a/packages/chain-mon/src/index.ts b/packages/chain-mon/src/index.ts index 98817368bbeb5..8e4d4163c0a19 100644 --- a/packages/chain-mon/src/index.ts +++ b/packages/chain-mon/src/index.ts @@ -1,5 +1,6 @@ export * from './balance-mon/service' export * from './drippie-mon/service' +export * from './fault-mon/index' +export * from './multisig-mon/service' export * from './wd-mon/service' export * from './wallet-mon/service' -export * from './fault-mon/index' diff --git a/packages/chain-mon/src/multisig-mon/service.ts b/packages/chain-mon/src/multisig-mon/service.ts new file mode 100644 index 0000000000000..87677b79430c8 --- /dev/null +++ b/packages/chain-mon/src/multisig-mon/service.ts @@ -0,0 +1,109 @@ +import { + BaseServiceV2, + StandardOptions, + Gauge, + Counter, + validators, +} from '@eth-optimism/common-ts' +import { Provider } from '@ethersproject/abstract-provider' +import { BigNumber, ethers } from 'ethers' + +import Safe from '../abi/IGnosisSafe.0.8.19.json' +import { version } from '../../package.json' + +type MultisigMonOptions = { + rpc: Provider + accounts: string +} + +type MultisigMonMetrics = { + safeNonce: Gauge + unexpectedRpcErrors: Counter +} + +type MultisigMonState = { + accounts: Array<{ address: string; nickname: string; safe: boolean }> +} + +export class MultisigMonService extends BaseServiceV2< + MultisigMonOptions, + MultisigMonMetrics, + MultisigMonState +> { + constructor(options?: Partial) { + super({ + version, + name: 'balance-mon', + loop: true, + options: { + loopIntervalMs: 60_000, + ...options, + }, + optionsSpec: { + rpc: { + validator: validators.provider, + desc: 'Provider for network to monitor balances on', + }, + accounts: { + validator: validators.str, + desc: 'JSON array of [{ address, nickname, safe }] to monitor balances and nonces of', + public: true, + }, + }, + metricsSpec: { + safeNonce: { + type: Gauge, + desc: 'Safe nonce', + labels: ['address', 'nickname'], + }, + unexpectedRpcErrors: { + type: Counter, + desc: 'Number of unexpected RPC errors', + labels: ['section', 'name'], + }, + }, + }) + } + + protected async init(): Promise { + this.state.accounts = JSON.parse(this.options.accounts) + } + + protected async main(): Promise { + for (const account of this.state.accounts) { + try { + const safeContract = new ethers.Contract( + account.address, + Safe.abi, + this.options.rpc + ) + const safeNonce = BigNumber.from(await safeContract.nonce()) + this.logger.info(`got nonce`, { + address: account.address, + nickname: account.nickname, + nonce: safeNonce.toString(), + }) + + this.metrics.safeNonce.set( + { address: account.address, nickname: account.nickname }, + parseInt(safeNonce.toString(), 10) + ) + } catch (err) { + this.logger.info(`got unexpected RPC error`, { + section: 'safeNonce', + name: 'getSafeNonce', + err, + }) + this.metrics.unexpectedRpcErrors.inc({ + section: 'safeNonce', + name: 'getSafeNonce', + }) + } + } + } +} + +if (require.main === module) { + const service = new MultisigMonService() + service.run() +}