From f805344dfc90b9a910ac95603b57e8c51bfd71ed Mon Sep 17 00:00:00 2001 From: Christopher Dimitri Sastropranoto Date: Sat, 4 Jun 2022 00:21:36 +0800 Subject: [PATCH] Metis support for the Layer2 Sequencer Health EA (#1913) * add support to track metis health * remove unused code in l2 sequencer health EA * address PR feedback * force pipeline --- .changeset/curly-lions-travel.md | 5 +++++ .../sources/layer2-sequencer-health/README.md | 22 ++++++++++++------- .../layer2-sequencer-health/schemas/env.json | 8 +++++++ .../src/config/index.ts | 9 ++++++++ .../src/endpoint/health.ts | 19 +++++++--------- .../layer2-sequencer-health/src/network.ts | 8 +++++++ 6 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 .changeset/curly-lions-travel.md diff --git a/.changeset/curly-lions-travel.md b/.changeset/curly-lions-travel.md new file mode 100644 index 0000000000..c103e08b57 --- /dev/null +++ b/.changeset/curly-lions-travel.md @@ -0,0 +1,5 @@ +--- +'@chainlink/layer2-sequencer-health-adapter': minor +--- + +add support for metis to layer2-sequencer-health EA diff --git a/packages/sources/layer2-sequencer-health/README.md b/packages/sources/layer2-sequencer-health/README.md index 3f3e057b69..f7476575bf 100644 --- a/packages/sources/layer2-sequencer-health/README.md +++ b/packages/sources/layer2-sequencer-health/README.md @@ -13,6 +13,8 @@ Adapter that checks the Layer 2 Sequencer status | | `ARBITRUM_HEALTH_ENDPOINT` | Arbitrum Health Endpoint | | | | | `OPTIMISM_RPC_ENDPOINT` | Optimism RPC Endpoint | | https://mainnet.optimism.io | | | `OPTIMISM_HEALTH_ENDPOINT` | Optimism Health Endpoint | | https://mainnet-sequencer.optimism.io/health | +| | `METIS_RPC_ENDPOINT` | Metis RPC Endpoint | | https://andromeda.metis.io/?owner=1088 | +| | `METIS_HEALTH_ENDPOINT` | Metis Health Endpoint | | https://tokenapi.metis.io/andromeda/health | For the adapter to be useful on the desired network, at least one endpoint (RPC or HEALTH) needs to provided @@ -20,9 +22,9 @@ For the adapter to be useful on the desired network, at least one endpoint (RPC ### Input Parameters -| Required? | Name | Description | Options | Defaults to | -| :-------: | :-----: | :----------------------: | :------------------: | :---------: | -| ✅ | network | Layer 2 Network to check | arbitrum or optimism | | +| Required? | Name | Description | Options | Defaults to | +| :-------: | :-----: | :----------------------: | :-----------------------------: | :---------: | +| ✅ | network | Layer 2 Network to check | `arbitrum`, `optimism`, `metis` | | --- @@ -39,13 +41,17 @@ For the adapter to be useful on the desired network, at least one endpoint (RPC ### Sample Output +0 = Sequencer is healthy +1 = Sequencer is unhealthy + ```json { - "jobRunID": "278c97ffadb54a5bbb93cfec5f7b5503", + "jobRunID": "1", + "result": 0, + "statusCode": 200, "data": { - "result": true, - "isHealthy": true - }, - "statusCode": 200 + "isHealthy": true, + "result": 0 + } } ``` diff --git a/packages/sources/layer2-sequencer-health/schemas/env.json b/packages/sources/layer2-sequencer-health/schemas/env.json index efb4b64708..10c392c494 100644 --- a/packages/sources/layer2-sequencer-health/schemas/env.json +++ b/packages/sources/layer2-sequencer-health/schemas/env.json @@ -23,6 +23,14 @@ "OPTIMISM_HEALTH_ENDPOINT": { "type": "string", "default": "https://mainnet-sequencer.optimism.io/health" + }, + "METIS_RPC_ENDPOINT": { + "type": "string", + "default": "https://andromeda.metis.io/?owner=1088" + }, + "METIS_HEALTH_ENDPOINT": { + "type": "string", + "default": "https://tokenapi.metis.io/andromeda/health" } }, "allOf": [ diff --git a/packages/sources/layer2-sequencer-health/src/config/index.ts b/packages/sources/layer2-sequencer-health/src/config/index.ts index 05a1d794ef..8723c4f4ae 100644 --- a/packages/sources/layer2-sequencer-health/src/config/index.ts +++ b/packages/sources/layer2-sequencer-health/src/config/index.ts @@ -18,16 +18,21 @@ export const DEFAULT_TIMEOUT_LIMIT = 5 * 1000 export enum Networks { Arbitrum = 'arbitrum', Optimism = 'optimism', + Metis = 'metis', } const DEFAULT_ARBITRUM_RPC_ENDPOINT = 'https://arb1.arbitrum.io/rpc' const DEFAULT_OPTIMISM_RPC_ENDPOINT = 'https://mainnet.optimism.io' +const DEFAULT_METIS_RPC_ENDPOINT = 'https://andromeda.metis.io/?owner=1088' + export const RPC_ENDPOINTS = { [Networks.Arbitrum]: util.getEnv('ARBITRUM_RPC_ENDPOINT') || DEFAULT_ARBITRUM_RPC_ENDPOINT, [Networks.Optimism]: util.getEnv('OPTIMISM_RPC_ENDPOINT') || DEFAULT_OPTIMISM_RPC_ENDPOINT, + [Networks.Metis]: util.getEnv('METIS_RPC_ENDPOINT') || DEFAULT_METIS_RPC_ENDPOINT, } const DEFAULT_OPTIMISM_HEALTH_ENDPOINT = 'https://mainnet-sequencer.optimism.io/health' +const DEFAULT_METIS_HEALTH_ENDPOINT = 'https://tokenapi.metis.io/andromeda/health' export const HEALTH_ENDPOINTS = { [Networks.Arbitrum]: { endpoint: util.getEnv('ARBITRUM_HEALTH_ENDPOINT'), @@ -37,6 +42,10 @@ export const HEALTH_ENDPOINTS = { endpoint: util.getEnv('OPTIMISM_HEALTH_ENDPOINT') || DEFAULT_OPTIMISM_HEALTH_ENDPOINT, responsePath: ['healthy'], }, + [Networks.Metis]: { + endpoint: util.getEnv('METIS_HEALTH_ENDPOINT') || DEFAULT_METIS_HEALTH_ENDPOINT, + responsePath: ['healthy'], + }, } export interface ExtendedConfig extends Config { diff --git a/packages/sources/layer2-sequencer-health/src/endpoint/health.ts b/packages/sources/layer2-sequencer-health/src/endpoint/health.ts index bf0bc4720d..c33159cefd 100644 --- a/packages/sources/layer2-sequencer-health/src/endpoint/health.ts +++ b/packages/sources/layer2-sequencer-health/src/endpoint/health.ts @@ -4,7 +4,6 @@ import { ExtendedConfig, Networks } from '../config' import { requestBlockHeight, getSequencerHealth, - // getL1RollupStatus, NetworkHealthCheck, getStatusByTransaction, } from '../network' @@ -60,6 +59,7 @@ export const makeNetworkStatusCheck = ( const networks: Record Promise> = { [Networks.Arbitrum]: makeNetworkStatusCheck(Networks.Arbitrum), [Networks.Optimism]: makeNetworkStatusCheck(Networks.Optimism), + [Networks.Metis]: makeNetworkStatusCheck(Networks.Metis), } export const getL2NetworkStatus: NetworkHealthCheck = ( @@ -86,17 +86,19 @@ export const execute: ExecuteWithConfig = async (request, _, con return isHealthy ? 0 : 1 } - const _respond = (isHealthy: boolean) => - Requester.success( + const _respond = (isHealthy: boolean) => { + const result = _translateIntoFeedResponse(isHealthy) + return Requester.success( jobRunID, { data: { - isHealthy: _translateIntoFeedResponse(isHealthy), - result: _translateIntoFeedResponse(isHealthy), + isHealthy: result === 0, + result, }, }, config.verbose, ) + } const _tryMethod = (fn: NetworkHealthCheck) => @@ -120,14 +122,9 @@ export const execute: ExecuteWithConfig = async (request, _, con // #1 Option: Direct check on health endpoint // #2 Option: Check block height - // #3 Option: Check L1 Rollup Contract // If every method succeeds, the Network is considered healthy // If any method fails, an empty tx is sent. This determines the final state - const wrappedMethods = [ - getSequencerHealth, - getL2NetworkStatus, - // , getL1RollupStatus // TODO - ].map(_tryMethod) + const wrappedMethods = [getSequencerHealth, getL2NetworkStatus].map(_tryMethod) for (let i = 0; i < wrappedMethods.length; i++) { const method = wrappedMethods[i] const isHealthy = await method(network, config.delta, config.deltaBlocks) diff --git a/packages/sources/layer2-sequencer-health/src/network.ts b/packages/sources/layer2-sequencer-health/src/network.ts index b87b341369..fbce435f18 100644 --- a/packages/sources/layer2-sequencer-health/src/network.ts +++ b/packages/sources/layer2-sequencer-health/src/network.ts @@ -72,6 +72,7 @@ export const getStatusByTransaction = async ( [Networks.Arbitrum]: ['gas price too low', 'forbidden sender address'], // TODO: Optimism error needs to be confirmed by their team [Networks.Optimism]: ['cannot accept 0 gas price transaction'], + [Networks.Metis]: ['cannot accept 0 gas price transaction'], } const networkTx: Record = { @@ -88,11 +89,18 @@ export const getStatusByTransaction = async ( gasPrice: 0, to: wallet.address, }, + [Networks.Metis]: { + value: 0, + gasLimit: 0, + gasPrice: 0, + to: wallet.address, + }, } const _getErrorMessage = (e: Record): string => { const paths = { [Networks.Arbitrum]: ['error', 'message'], [Networks.Optimism]: ['error', 'message'], + [Networks.Metis]: ['error', 'message'], } return (Requester.getResult(e, paths[network]) as string) || '' }