Skip to content

Commit 292b1e0

Browse files
committed
Add arbitrum monitoring (first pass)
1 parent da00765 commit 292b1e0

File tree

1 file changed

+116
-3
lines changed

1 file changed

+116
-3
lines changed

scripts/status.js

+116-3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,23 @@ async function getRPCLatestBlock(url) {
5353
}
5454
}
5555

56+
async function getBlockIngestorLatestBlock(url) {
57+
const res = await fetch(url, {
58+
method: 'POST',
59+
headers: {
60+
'Content-Type': 'application/json',
61+
},
62+
body: JSON.stringify({
63+
"query": "query test {\n getIngestorStats(id: \"STATS\") {\n value\n }\n}\n",
64+
"variables": {},
65+
"operationName": "test"
66+
})
67+
});
68+
const output = await res.json()
69+
const stats = JSON.parse(output.data.getIngestorStats.value);
70+
return parseInt(stats.lastBlockNumber,10);
71+
}
72+
5673
async function getBlockscoutLatestBlock() {
5774
try {
5875
const blockScoutBlock = await fetch("https://blockscout.com/xdai/mainnet/api?module=block&action=eth_block_number")
@@ -74,7 +91,7 @@ async function getBalance(account, url) {
7491
body: JSON.stringify({
7592
"jsonrpc":"2.0",
7693
"method":"eth_getBalance",
77-
"params":[account],
94+
"params":[account, "latest"],
7895
"id":1
7996
})
8097
})
@@ -112,8 +129,8 @@ module.exports = robot => {
112129
return "🔴";
113130
}
114131

115-
async function getMessage() {
116-
let message = ""
132+
async function getMessageGnosis() {
133+
let message = "**On Gnosis:**\n"
117134
// Get latest block from graph
118135
const graphNumberRes = getGraphLatestBlock("https://xdai.colony.io/graph/subgraphs/name/joinColony/subgraph")
119136

@@ -250,6 +267,77 @@ module.exports = robot => {
250267
return message
251268
}
252269

270+
async function getArbitrumMessage() {
271+
272+
const ARBITRUM_MINER_ADDRESS = "0xd090822a84e037Acc8a169C54a5943FF9fB82236"
273+
const ARBITRUM_BROADCASTER_ADDRESS = "0xf4ab92A14c7CBc232E8293C59DfFbd98Fbdf9b3E"
274+
const ARBITRUM_NETWORK_ADDRESS = "0xcccccdcc0ccf6c708d860e19353c5f9a49accccc"
275+
const ARBITRUM_GRAPH_URL = "https://arbitrum.colony.io/auth-proxy/graphql"
276+
const ourRPC = process.env.ARBITRUM_RPC
277+
const publicRPC = process.env.ARBITRUM_PUBLIC_RPC
278+
279+
280+
// Get latest block from our RPC
281+
const ourRpcPromise = getRPCLatestBlock(ourRPC);
282+
283+
// Get latest block from another RPC
284+
const publicRPCPromise = getRPCLatestBlock(publicRPC);
285+
286+
// Get latest block from block ingestor
287+
const blockIngestorNumberPromise = getBlockIngestorLatestBlock(ARBITRUM_GRAPH_URL);
288+
289+
// Get balance of miner
290+
const balancePromise = await getBalance(ARBITRUM_MINER_ADDRESS, ourRPC)
291+
292+
// Get balance of MTX Broadcaster
293+
const mtxBalancePromise = await getBalance(ARBITRUM_BROADCASTER_ADDRESS, ourRPC)
294+
295+
const [ourRpcBlock, publicRpcBlock, ingestorNumber, minerBalance, mtxBalance] = await Promise.all([ourRpcPromise, publicRPCPromise, blockIngestorNumberPromise, balancePromise, mtxBalancePromise])
296+
297+
// Get time since last mining cycle completed
298+
// Get reputation mining cycle status
299+
let secondsSinceOpen = -1;
300+
let nSubmitted = -1;
301+
try {
302+
let provider;
303+
// Use our RPC if okay
304+
if (ourRpcBlock > 0){
305+
provider = new ethers.providers.JsonRpcProvider(ourRPC)
306+
} else {
307+
provider = new ethers.providers.JsonRpcProvider(publicRPC);
308+
}
309+
310+
const cn = new ethers.Contract(ARBITRUM_NETWORK_ADDRESS, networkABI, provider)
311+
const miningAddress = await cn.getReputationMiningCycle(true);
312+
313+
const rm = new ethers.Contract(miningAddress, miningABI, provider);
314+
const openTimestamp = await rm.getReputationMiningWindowOpenTimestamp();
315+
secondsSinceOpen = Math.floor(Date.now()/1000) - openTimestamp;
316+
317+
nSubmitted = await rm.getNUniqueSubmittedHashes();
318+
} catch (err) {
319+
// Use default values for anything not set
320+
}
321+
322+
let message = "**On Arbitrum:**\n"
323+
message += `Public RPC latest block: ${publicRpcBlock}\n`
324+
const rpcDiscrepancy = Math.abs(ourRpcBlock-publicRpcBlock)
325+
message += `${status(rpcDiscrepancy, 60, 120)} Our RPC latest block: ${ourRpcBlock}\n`
326+
message += `${status(ingestorNumber-ourRpcBlock, 25*GRAPH_LAG_INCIDENT/2, 25*GRAPH_LAG_INCIDENT)} Our ingestor latest block: ${ingestorNumber}\n`
327+
message += `${status(-minerBalance, -0.05, -0.01)} Miner balance (\`${ARBITRUM_MINER_ADDRESS.slice(0, 6)}...${ARBITRUM_MINER_ADDRESS.slice(-4)}\`): ${minerBalance}\n`
328+
message += `${status(-mtxBalance, -0.1, -0.01)} Metatx broadcaster balance (\`${ARBITRUM_BROADCASTER_ADDRESS.slice(0, 6)}...${ARBITRUM_BROADCASTER_ADDRESS.slice(-4)}\`): ${mtxBalance}\n`
329+
message += `${status(secondsSinceOpen, 3600, 4500)} Time since last mining cycle completed: ${(secondsSinceOpen/60).toFixed(0)} minutes\n`
330+
message += `${status(nSubmitted, 2,10000)} ${nSubmitted} unique submissions so far this cycle\n`
331+
return message;
332+
}
333+
334+
async function getMessage() {
335+
const gnosisMessage = await getMessageGnosis();
336+
const arbitrumMessage = await getArbitrumMessage();
337+
return arbitrumMessage + "\n" + gnosisMessage;
338+
}
339+
340+
253341
robot.hear(/^!status$/, async () => {
254342
const message = await getMessage();
255343
channel.send(message)
@@ -276,6 +364,17 @@ module.exports = robot => {
276364
}
277365
}
278366

367+
async function checkStatusArbitrum(){
368+
const message = await getArbitrumMessage();
369+
if (message.indexOf("🔴 Our graph latest block") != -1 && !ongoingGraphIncident) {
370+
ongoingGraphIncident = true;
371+
channel.send("There appears to be an incident with the graph. \n" + message)
372+
} else if (message.indexOf("🔴") != -1 && !ongoingGenericIncident && !ongoingGraphIncident){
373+
ongoingGenericIncident = true;
374+
channel.send("There appears to be a generic incident. \n" + message)
375+
}
376+
}
377+
279378
const setupCronJob = () => {
280379
const job = new CronJob({
281380
// Every minute
@@ -288,6 +387,20 @@ module.exports = robot => {
288387
timeZone: 'Pacific/Niue'
289388
})
290389
job.start()
390+
391+
392+
const arbitrumJob = new CronJob({
393+
// Every minute
394+
cronTime: '00 * * * * *',
395+
onTick: () => {
396+
checkStatusArbitrum()
397+
},
398+
start: true,
399+
// Last time zone of the day (UTC-11)
400+
timeZone: 'Pacific/Niue'
401+
})
402+
arbitrumJob.start()
403+
291404
}
292405
setupCronJob()
293406
}

0 commit comments

Comments
 (0)