Commit d798e075 authored by felipe's avatar felipe Committed by GitHub

Merge pull request #8107 from ethereum-optimism/felipe/add-safe-nonce-mon-to-chain-mon

feat(chain-mon): monitor safe nonce as a metric
parents 3b284850 ac3dc603
This diff is collapsed.
...@@ -6,8 +6,9 @@ import { ...@@ -6,8 +6,9 @@ import {
validators, validators,
} from '@eth-optimism/common-ts' } from '@eth-optimism/common-ts'
import { Provider } from '@ethersproject/abstract-provider' import { Provider } from '@ethersproject/abstract-provider'
import { ethers } from 'ethers' import { BigNumber, ethers } from 'ethers'
import Safe from '../abi/IGnosisSafe.0.8.19.json'
import { version } from '../../package.json' import { version } from '../../package.json'
type BalanceMonOptions = { type BalanceMonOptions = {
...@@ -17,11 +18,12 @@ type BalanceMonOptions = { ...@@ -17,11 +18,12 @@ type BalanceMonOptions = {
type BalanceMonMetrics = { type BalanceMonMetrics = {
balances: Gauge balances: Gauge
safeNonces: Gauge
unexpectedRpcErrors: Counter unexpectedRpcErrors: Counter
} }
type BalanceMonState = { type BalanceMonState = {
accounts: Array<{ address: string; nickname: string }> accounts: Array<{ address: string; nickname: string; safe: boolean }>
} }
export class BalanceMonService extends BaseServiceV2< export class BalanceMonService extends BaseServiceV2<
...@@ -45,7 +47,7 @@ export class BalanceMonService extends BaseServiceV2< ...@@ -45,7 +47,7 @@ export class BalanceMonService extends BaseServiceV2<
}, },
accounts: { accounts: {
validator: validators.str, validator: validators.str,
desc: 'JSON array of [{ address, nickname }] to monitor balances of', desc: 'JSON array of [{ address, nickname, safe }] to monitor balances and nonces of',
public: true, public: true,
}, },
}, },
...@@ -55,6 +57,11 @@ export class BalanceMonService extends BaseServiceV2< ...@@ -55,6 +57,11 @@ export class BalanceMonService extends BaseServiceV2<
desc: 'Balances of addresses', desc: 'Balances of addresses',
labels: ['address', 'nickname'], labels: ['address', 'nickname'],
}, },
safeNonces: {
type: Gauge,
desc: 'Safe nonce',
labels: ['address', 'nickname'],
},
unexpectedRpcErrors: { unexpectedRpcErrors: {
type: Counter, type: Counter,
desc: 'Number of unexpected RPC errors', desc: 'Number of unexpected RPC errors',
...@@ -70,9 +77,21 @@ export class BalanceMonService extends BaseServiceV2< ...@@ -70,9 +77,21 @@ export class BalanceMonService extends BaseServiceV2<
protected async main(): Promise<void> { protected async main(): Promise<void> {
for (const account of this.state.accounts) { for (const account of this.state.accounts) {
let balance: ethers.BigNumber
try { try {
balance = await this.options.rpc.getBalance(account.address) const balance = await this.options.rpc.getBalance(account.address)
this.logger.info(`got balance`, {
address: account.address,
nickname: account.nickname,
balance: balance.toString(),
})
// Parse the balance as an integer instead of via toNumber() to avoid ethers throwing an
// an error. We might get rounding errors but we don't need perfect precision here, just a
// generally accurate sense for what the current balance is.
this.metrics.balances.set(
{ address: account.address, nickname: account.nickname },
parseInt(balance.toString(), 10)
)
} catch (err) { } catch (err) {
this.logger.info(`got unexpected RPC error`, { this.logger.info(`got unexpected RPC error`, {
section: 'balances', section: 'balances',
...@@ -83,22 +102,39 @@ export class BalanceMonService extends BaseServiceV2< ...@@ -83,22 +102,39 @@ export class BalanceMonService extends BaseServiceV2<
section: 'balances', section: 'balances',
name: 'getBalance', name: 'getBalance',
}) })
continue
} }
this.logger.info(`got balance`, { // Get the safe nonce to report
address: account.address, if (account.safe) {
nickname: account.nickname, try {
balance: balance.toString(), 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(),
})
// Parse the balance as an integer instead of via toNumber() to avoid ethers throwing an this.metrics.safeNonces.set(
// an error. We might get rounding errors but we don't need perfect precision here, just a { address: account.address, nickname: account.nickname },
// generally accurate sense for what the current balance is. parseInt(safeNonce.toString(), 10)
this.metrics.balances.set( )
{ address: account.address, nickname: account.nickname }, } catch (err) {
parseInt(balance.toString(), 10) this.logger.info(`got unexpected RPC error`, {
) section: 'safeNonce',
name: 'getSafeNonce',
err,
})
this.metrics.unexpectedRpcErrors.inc({
section: 'safeNonce',
name: 'getSafeNonce',
})
}
}
} }
} }
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
}, },
"include": [ "include": [
"package.json", "package.json",
"src/abi/IGnosisSafe.0.8.19.json",
"src/**/*" "src/**/*"
] ]
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment