Commit 9fc86361 authored by Felipe Andrade's avatar Felipe Andrade

feat(chain-mon): monitor safe nonce as a metric

parent 97cfa03b
......@@ -6,7 +6,7 @@ import {
validators,
} from '@eth-optimism/common-ts'
import { Provider } from '@ethersproject/abstract-provider'
import { ethers } from 'ethers'
import { BigNumber, ethers } from 'ethers'
import { version } from '../../package.json'
......@@ -17,11 +17,12 @@ type BalanceMonOptions = {
type BalanceMonMetrics = {
balances: Gauge
safeNonces: Gauge
unexpectedRpcErrors: Counter
}
type BalanceMonState = {
accounts: Array<{ address: string; nickname: string }>
accounts: Array<{ address: string; nickname: string; safe: boolean }>
}
export class BalanceMonService extends BaseServiceV2<
......@@ -45,7 +46,7 @@ export class BalanceMonService extends BaseServiceV2<
},
accounts: {
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,
},
},
......@@ -55,6 +56,11 @@ 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',
......@@ -73,6 +79,19 @@ export class BalanceMonService extends BaseServiceV2<
let balance: ethers.BigNumber
try {
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) {
this.logger.info(`got unexpected RPC error`, {
section: 'balances',
......@@ -83,22 +102,40 @@ export class BalanceMonService extends BaseServiceV2<
section: 'balances',
name: 'getBalance',
})
continue
}
this.logger.info(`got balance`, {
address: account.address,
nickname: account.nickname,
balance: balance.toString(),
})
// Get the safe nonce to report
if (account.safe) {
let safeNonce: ethers.BigNumber
try {
safeNonce = BigNumber.from(
await this.options.rpc.call({
to: account.address,
data: '0xaffed0e0', // call the nonce() function in the safe contract
})
)
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
// 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)
)
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',
})
}
}
}
}
}
......
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