From 0ccf2cf962e1b4b40b3f391085f7273dcaa001af Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 5 Jun 2023 10:48:14 -0600 Subject: [PATCH 01/11] feat(hapi): add healthcheck for p2p endpoints --- hapi/src/services/node.service.js | 2 +- hapi/src/services/producer.service.js | 15 +++++++++++++-- hapi/src/utils/eos.util.js | 1 + hapi/src/utils/producer.util.js | 25 +++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/hapi/src/services/node.service.js b/hapi/src/services/node.service.js index ac558fc4..b8a33ee8 100644 --- a/hapi/src/services/node.service.js +++ b/hapi/src/services/node.service.js @@ -42,7 +42,7 @@ const updateNodes = async (nodes = []) => { } const updateEndpointInfo = async endpoint => { - if (!endpoint.type || !['api', 'ssl'].includes(endpoint.type)) return + if (!endpoint.type || !['api', 'ssl', 'p2p'].includes(endpoint.type)) return const updateMutation = ` mutation ($id: uuid, $head_block_time: timestamptz, $response: jsonb, $updated_at: timestamptz,) { diff --git a/hapi/src/services/producer.service.js b/hapi/src/services/producer.service.js index a7418a09..2fe56f8e 100644 --- a/hapi/src/services/producer.service.js +++ b/hapi/src/services/producer.service.js @@ -147,7 +147,7 @@ const syncNodes = async producers => { const syncEndpoints = async () => { const query = ` { - endpoint_aggregate(where: {type: {_in: ["api", "ssl"]}}) { + endpoint_aggregate(where: {type: {_in: ["api", "ssl", "p2p"]}}) { aggregate { count } @@ -155,7 +155,7 @@ const syncEndpoints = async () => { producers : producer(where: {nodes: {endpoints: {_and: [{value: {_gt: ""}}]}}}, order_by: {rank: asc}) { id nodes { - endpoints(where: {type: {_in: ["api", "ssl"]}}) { + endpoints(where: {type: {_in: ["api", "ssl", "p2p"]}}) { id value type @@ -241,6 +241,17 @@ const getHealthCheckResponse = async endpoint => { let startTime let response + if (endpoint.type === 'p2p') { + startTime = new Date() + const result = await producerUtil.isP2PResponding(endpoint.value) + + return { + startTime, + status: result ? 200 : null, + statusText: result ? 'P2P is responding' : null + } + } + if (endpoint?.features?.length) { for (const API of eosConfig.healthCheckAPIs) { if (endpoint.features?.some(feature => feature === API.name)) { diff --git a/hapi/src/utils/eos.util.js b/hapi/src/utils/eos.util.js index acecdc33..537b425d 100644 --- a/hapi/src/utils/eos.util.js +++ b/hapi/src/utils/eos.util.js @@ -259,6 +259,7 @@ const getProducers = async options => const getInfo = options => eosApi.getInfo(options || {}) module.exports = { + callWithTimeout, newAccount, generateRandomAccountName, getAccount, diff --git a/hapi/src/utils/producer.util.js b/hapi/src/utils/producer.util.js index 996ddb4c..09ef2d09 100644 --- a/hapi/src/utils/producer.util.js +++ b/hapi/src/utils/producer.util.js @@ -1,6 +1,8 @@ const axiosUtil = require('./axios.util') const eosUtil = require('./eos.util') const hasuraUtil = require('./hasura.util') +const net = require('node:net') + const { eosConfig } = require('../config') const getUrlStatus = async (url, api = '') => { @@ -16,6 +18,28 @@ const getUrlStatus = async (url, api = '') => { } } +const isP2PResponding = async endpoint => { + const splitted = endpoint?.split(':') || {} + const { [0]: host, [1]: port } = splitted + + if (splitted.length !== 2 || !host || !port) return false + + const isResponding = new Promise((resolve, _) => { + const client = net.createConnection({ host, port }, () => { + client.destroy() + resolve(true) + }) + + client.on('error', _ => { + resolve(false) + }) + }) + + return eosUtil.callWithTimeout(isResponding, 60000).catch(_ => { + return false + }) +} + const getNodeInfo = async (url, api = '/v1/chain/get_info') => { const response = await getUrlStatus(url, api) @@ -263,6 +287,7 @@ const jsonParse = (string) => { } module.exports = { + isP2PResponding, getNodeInfo, getEndpoints, getExpectedRewards, From 13a6cc224ae0d8ee6effeb5b96489e9e7226bf99 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 5 Jun 2023 15:35:01 -0600 Subject: [PATCH 02/11] feat(hapi): split healthcheck of P2P and API endpoints --- hapi/src/services/producer.service.js | 54 ++++++++++++++++++++------- hapi/src/utils/eos.util.js | 13 ++++--- hapi/src/utils/producer.util.js | 27 +++++++++++--- 3 files changed, 70 insertions(+), 24 deletions(-) diff --git a/hapi/src/services/producer.service.js b/hapi/src/services/producer.service.js index 2fe56f8e..b012e790 100644 --- a/hapi/src/services/producer.service.js +++ b/hapi/src/services/producer.service.js @@ -145,9 +145,14 @@ const syncNodes = async producers => { } const syncEndpoints = async () => { + await syncAPIEndpoints() + await syncP2PEndpoints() +} + +const syncAPIEndpoints = async () => { const query = ` { - endpoint_aggregate(where: {type: {_in: ["api", "ssl", "p2p"]}}) { + endpoint_aggregate(where: {type: {_in: ["api", "ssl"]}}) { aggregate { count } @@ -155,7 +160,7 @@ const syncEndpoints = async () => { producers : producer(where: {nodes: {endpoints: {_and: [{value: {_gt: ""}}]}}}, order_by: {rank: asc}) { id nodes { - endpoints(where: {type: {_in: ["api", "ssl", "p2p"]}}) { + endpoints(where: {type: {_in: ["api", "ssl"]}}) { id value type @@ -193,6 +198,40 @@ const syncEndpoints = async () => { await healthCheckHistoryService.saveHealthRegister(endpoints.flat()) } +const syncP2PEndpoints = async () => { + const query = ` + { + endpoint_aggregate(where: {type: {_in: ["p2p"]}}) { + aggregate { + count + } + } + endpoints : endpoint(where: {type: {_in: ["p2p"]}}) { + id + value + type + } + } + ` + const { + endpoints, + endpoint_aggregate: { + aggregate: { count } + } + } = await hasuraUtil.request(query) + + if (!count) return + + for (const endpoint of endpoints){ + const result = await producerUtil.isP2PResponding(endpoint.value) + + endpoint.response = result + endpoint.updated_at = new Date() + + await nodeService.updateEndpointInfo(endpoint) + } +} + const endpointsHealth = async (endpoints, producerId) => { const checkedList = [] @@ -241,17 +280,6 @@ const getHealthCheckResponse = async endpoint => { let startTime let response - if (endpoint.type === 'p2p') { - startTime = new Date() - const result = await producerUtil.isP2PResponding(endpoint.value) - - return { - startTime, - status: result ? 200 : null, - statusText: result ? 'P2P is responding' : null - } - } - if (endpoint?.features?.length) { for (const API of eosConfig.healthCheckAPIs) { if (endpoint.features?.some(feature => feature === API.name)) { diff --git a/hapi/src/utils/eos.util.js b/hapi/src/utils/eos.util.js index 537b425d..0fc0d5f8 100644 --- a/hapi/src/utils/eos.util.js +++ b/hapi/src/utils/eos.util.js @@ -61,11 +61,14 @@ const callWithTimeout = async (promise, ms) => { timeoutID = setTimeout(() => reject(new Error(timeoutMessage)), ms) }) - return Promise.race([promise, timeoutPromise]).then((response) => { - clearTimeout(timeoutID) - - return response - }) + return Promise.race([promise, timeoutPromise]) + .then(response => response) + .catch(error => { + throw error + }) + .finally(() => { + clearTimeout(timeoutID) + }) } const newAccount = async accountName => { diff --git a/hapi/src/utils/producer.util.js b/hapi/src/utils/producer.util.js index 09ef2d09..a7633bb0 100644 --- a/hapi/src/utils/producer.util.js +++ b/hapi/src/utils/producer.util.js @@ -2,6 +2,7 @@ const axiosUtil = require('./axios.util') const eosUtil = require('./eos.util') const hasuraUtil = require('./hasura.util') const net = require('node:net') +const os = require('node:os') const { eosConfig } = require('../config') @@ -22,21 +23,35 @@ const isP2PResponding = async endpoint => { const splitted = endpoint?.split(':') || {} const { [0]: host, [1]: port } = splitted - if (splitted.length !== 2 || !host || !port) return false + if (splitted.length !== 2 || !host || !port) + return { status: 'Failed', statusText: 'Invalid endpoint format' } const isResponding = new Promise((resolve, _) => { const client = net.createConnection({ host, port }, () => { client.destroy() - resolve(true) + resolve({ status: 'Success', statusText: 'Connection established' }) }) - client.on('error', _ => { - resolve(false) + client.on('error', err => { + let errorMessage = '' + + switch (Math.abs(err?.errno)) { + case os.constants.errno.ECONNREFUSED: + errorMessage = 'Connection refused' + break + case os.constants.errno.ETIMEDOUT: + errorMessage = 'Operation timed out' + break + default: + errorMessage = 'Connection error' + } + + resolve({ status: 'Failed', statusText: errorMessage }) }) }) - return eosUtil.callWithTimeout(isResponding, 60000).catch(_ => { - return false + return eosUtil.callWithTimeout(isResponding, 60000).catch((_) => { + return { status: 'Failed', statusText: 'Timeout Exhausted' } }) } From 7231b5cd19f5c23415bac221f3938c21fded87eb Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 5 Jun 2023 15:47:51 -0600 Subject: [PATCH 03/11] feat(webapp): remove filters to show healthcheck of P2P endpoints - fix(webapp): add shadow in no results component - fix(webaap): avoid duplicated endpoints in fastest endpoints table --- webapp/src/components/NoResults/styles.js | 1 + webapp/src/components/NodeCard/EndpointsChips.js | 7 +++---- webapp/src/gql/producer.gql.js | 2 +- webapp/src/hooks/customHooks/useEndpointsState.js | 5 +++-- webapp/src/language/en.json | 4 ++-- webapp/src/language/es.json | 4 ++-- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/webapp/src/components/NoResults/styles.js b/webapp/src/components/NoResults/styles.js index ca2bc707..1164aef3 100644 --- a/webapp/src/components/NoResults/styles.js +++ b/webapp/src/components/NoResults/styles.js @@ -6,5 +6,6 @@ export default (theme) => ({ marginBottom: theme.spacing(2), padding: theme.spacing(2), alignItems: 'center', + boxShadow: '0px 1px 5px rgba(0, 0, 0, 0.15) !important', }, }) diff --git a/webapp/src/components/NodeCard/EndpointsChips.js b/webapp/src/components/NodeCard/EndpointsChips.js index 602dee90..db985cbf 100644 --- a/webapp/src/components/NodeCard/EndpointsChips.js +++ b/webapp/src/components/NodeCard/EndpointsChips.js @@ -72,7 +72,6 @@ const EndpointsChips = ({ node }) => { ) } - const checkedEndpoints = node.endpoints.filter(endpoint => endpoint.type !== 'p2p') const status = { totalEndpoints: 0, failingEndpoints: [], @@ -80,14 +79,14 @@ const EndpointsChips = ({ node }) => { isLoading: false } - for (const endpoint of checkedEndpoints){ + for (const endpoint of node.endpoints){ if (endpoint?.response?.status === undefined) { status.isLoading = true break } - if (endpoint?.response?.status !== 200) { + if (endpoint?.response?.status !== 200 && endpoint?.response?.status !== 'Success') { status.failingEndpoints.push(endpoint.type) } @@ -99,7 +98,7 @@ const EndpointsChips = ({ node }) => { <>
{t('endpoints')} - {!!checkedEndpoints.length && } + {!!node.endpoints.length && }
{ diff --git a/webapp/src/gql/producer.gql.js b/webapp/src/gql/producer.gql.js index 7d522f64..1c204798 100644 --- a/webapp/src/gql/producer.gql.js +++ b/webapp/src/gql/producer.gql.js @@ -220,7 +220,7 @@ export const FASTEST_ENDPOINTS_QUERY = gql`query($today: date){ }` export const HISTORY_ENDPOINTS_BY_PRODUCER_QUERY = gql`query($id: Int){ - endpoints: check_history_by_endpoint(order_by: [{value: asc},{date: asc}], where: {producer_id: {_eq: $id}}) { + endpoints: check_history_by_endpoint(order_by: [{value: asc},{date: asc}], where: {producer_id: {_eq: $id}}, distinct_on: [value]) { value date avg_time diff --git a/webapp/src/hooks/customHooks/useEndpointsState.js b/webapp/src/hooks/customHooks/useEndpointsState.js index b321f560..29543c79 100644 --- a/webapp/src/hooks/customHooks/useEndpointsState.js +++ b/webapp/src/hooks/customHooks/useEndpointsState.js @@ -46,7 +46,8 @@ const useEndpointsState = () => { const handleFilter = useCallback(value => { const filter = value - ? { response: { _contains: { status: 200 } } } + ? { _or: [{ response: { _contains: { status: 200 } } }, + {response: { _contains: { status: "Success" }}}]} : { value: { _gt: '' } } setPagination(prev => ({ @@ -54,7 +55,7 @@ const useEndpointsState = () => { page: 1, where: { ...prev.where, nodes: { endpoints: filter } }, endpointFilter: value - ? { _or: [{ type: { _eq: 'p2p' } }, filter] } + ? filter : undefined, })) }, [setPagination]) diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index 4f197a50..8ab6f267 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -290,8 +290,8 @@ "cpuBenchmark": "CPU Benchmark Average", "isFull": "Is full", "supportedApis": "Supported APIs", - "allWorking": "All API and SSL endpoints are responding", - "noneWorking": "No API or SSL endpoints are responding", + "allWorking": "All endpoints are responding", + "noneWorking": "No endpoints are responding", "endpointPlural": "Endpoints not responding are the", "endpointSingular": "Endpoint not responding is the" }, diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 08187e58..5230ec6f 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -297,8 +297,8 @@ "cpuBenchmark": "Promedio del Benchmark de CPU", "isFull": "Es completo", "supportedApis": "APIs Soportadas", - "allWorking": "Todos los endpoints API y SSL están respondiendo", - "noneWorking": "Ningún endpoint API o SSL está respondiendo", + "allWorking": "Todos los endpoints están respondiendo", + "noneWorking": "Ningún endpoint está respondiendo", "endpointPlural": "Los endpoints que no responden son los", "endpointSingular": "El endpoint que no responde es el" }, From e35adc51e99eedf93ab8f0e8f7c116bb21a21b94 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 5 Jun 2023 16:22:31 -0600 Subject: [PATCH 04/11] fix(webapp): remove shadow from noResults component in the endpoints list --- webapp/src/routes/EndpointsList/index.js | 4 +++- webapp/src/routes/EndpointsList/styles.js | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/webapp/src/routes/EndpointsList/index.js b/webapp/src/routes/EndpointsList/index.js index 2ecaee41..57c8eecf 100644 --- a/webapp/src/routes/EndpointsList/index.js +++ b/webapp/src/routes/EndpointsList/index.js @@ -96,7 +96,9 @@ const EndpointsList = () => { {!!producers?.length ? ( ) : ( - +
+ +
)} {pagination.pages > 1 && (
diff --git a/webapp/src/routes/EndpointsList/styles.js b/webapp/src/routes/EndpointsList/styles.js index 70c1a80d..91f5b6b9 100644 --- a/webapp/src/routes/EndpointsList/styles.js +++ b/webapp/src/routes/EndpointsList/styles.js @@ -46,4 +46,9 @@ export default (theme) => ({ cardShadow: { boxShadow: '0px 1px 5px rgba(0, 0, 0, 0.15) !important', }, + noShadow: { + '& .MuiPaper-root':{ + boxShadow: 'none !important' + } + } }) From fb1a9f3aeebf15d0a9f7033509f2b18f8e4f4949 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 6 Jun 2023 10:31:05 -0600 Subject: [PATCH 05/11] perf(hapi): run the health check asynchronously --- hapi/src/services/producer.service.js | 7 +++---- hapi/src/utils/producer.util.js | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/hapi/src/services/producer.service.js b/hapi/src/services/producer.service.js index b012e790..9de6c39d 100644 --- a/hapi/src/services/producer.service.js +++ b/hapi/src/services/producer.service.js @@ -145,8 +145,7 @@ const syncNodes = async producers => { } const syncEndpoints = async () => { - await syncAPIEndpoints() - await syncP2PEndpoints() + Promise.all([syncP2PEndpoints(), syncAPIEndpoints()]) } const syncAPIEndpoints = async () => { @@ -222,14 +221,14 @@ const syncP2PEndpoints = async () => { if (!count) return - for (const endpoint of endpoints){ + await Promise.all(endpoints.map(async endpoint =>{ const result = await producerUtil.isP2PResponding(endpoint.value) endpoint.response = result endpoint.updated_at = new Date() await nodeService.updateEndpointInfo(endpoint) - } + })) } const endpointsHealth = async (endpoints, producerId) => { diff --git a/hapi/src/utils/producer.util.js b/hapi/src/utils/producer.util.js index a7633bb0..d8c2ad58 100644 --- a/hapi/src/utils/producer.util.js +++ b/hapi/src/utils/producer.util.js @@ -40,7 +40,7 @@ const isP2PResponding = async endpoint => { errorMessage = 'Connection refused' break case os.constants.errno.ETIMEDOUT: - errorMessage = 'Operation timed out' + errorMessage = 'Connection timeout exceeded' break default: errorMessage = 'Connection error' @@ -51,7 +51,7 @@ const isP2PResponding = async endpoint => { }) return eosUtil.callWithTimeout(isResponding, 60000).catch((_) => { - return { status: 'Failed', statusText: 'Timeout Exhausted' } + return { status: 'Failed', statusText: 'Connection timeout exceeded' } }) } From b4cca570e41783781ee23e15eb955db6665fce30 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 6 Jun 2023 10:33:36 -0600 Subject: [PATCH 06/11] feat(webapp): add P2P healthcheck in endpoints table --- webapp/src/components/EndpointsTable/index.js | 10 +++++----- webapp/src/components/EndpointsTextList/index.js | 2 +- webapp/src/components/HealthCheck/HealthCheckInfo.js | 2 +- webapp/src/language/es.json | 8 +++++++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/webapp/src/components/EndpointsTable/index.js b/webapp/src/components/EndpointsTable/index.js index 9f05820f..031a100f 100644 --- a/webapp/src/components/EndpointsTable/index.js +++ b/webapp/src/components/EndpointsTable/index.js @@ -52,6 +52,8 @@ const EndpointsTable = ({ producers }) => { const getStatus = endpoint => { if (endpoint.response.status === undefined) return + if (endpoint.response?.status === 'Success') return 'greenLight' + switch (Math.floor(endpoint.response?.status / 100)) { case 2: return !endpoint.head_block_time || isSynchronized(endpoint) @@ -77,11 +79,9 @@ const EndpointsTable = ({ producers }) => { key={`${producer?.name}-${endpointType}-${index}`} > {endpoint.value} - {endpointType !== 'p2p' && ( - - - - )} + + +
)) )} diff --git a/webapp/src/components/EndpointsTextList/index.js b/webapp/src/components/EndpointsTextList/index.js index 9c11bbd7..4f70f6cf 100644 --- a/webapp/src/components/EndpointsTextList/index.js +++ b/webapp/src/components/EndpointsTextList/index.js @@ -17,7 +17,7 @@ const EndpointsTextList = ({ type }) => { // Gets all responding endpoints useEffect(() => { setPagination(prev => ({ ...prev, limit: null })) - handleFilter(type !== 'p2p') + handleFilter(true) }, [type, handleFilter, setPagination]) useEffect(() => { diff --git a/webapp/src/components/HealthCheck/HealthCheckInfo.js b/webapp/src/components/HealthCheck/HealthCheckInfo.js index e86fc776..b03d4555 100644 --- a/webapp/src/components/HealthCheck/HealthCheckInfo.js +++ b/webapp/src/components/HealthCheck/HealthCheckInfo.js @@ -9,7 +9,7 @@ const HealthCheckInfo = ({ healthCheck }) => { return ( <> - {t('status')}: {healthCheck.response?.status || t('error')} + {t('status')}: {t(healthCheck.response?.status) || t('error')} {t('response')}: {t(healthCheck.response?.statusText || 'noResponse')} diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 5230ec6f..fff5d015 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -392,7 +392,13 @@ "Payment Required": "La solicitud requiere un pago", "Forbidden": "La solicitud está prohibida", "Request Timeout": "Tiempo de la solicitud superado", - "Too Many Request": "Demasiadas solicitudes" + "Too Many Request": "Demasiadas solicitudes", + "Connection refused": "Conexión rechazada", + "Connection timeout exceeded": "Tiempo de espera de conexión excedido", + "Connection error": "Error de conexión", + "Connection established": "Conexión establecida", + "Success": "Éxitosa", + "Failed": "Fallida" }, "nodeSearchComponent": { "title": "Buscar Nodo", From 2264d1bfd7722d476bbc9473153e1511dad0413d Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 6 Jun 2023 15:36:51 -0600 Subject: [PATCH 07/11] chore(hapi): add to endpoint response if it works --- hapi/src/services/producer.service.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hapi/src/services/producer.service.js b/hapi/src/services/producer.service.js index 9de6c39d..ec3a01ba 100644 --- a/hapi/src/services/producer.service.js +++ b/hapi/src/services/producer.service.js @@ -224,7 +224,7 @@ const syncP2PEndpoints = async () => { await Promise.all(endpoints.map(async endpoint =>{ const result = await producerUtil.isP2PResponding(endpoint.value) - endpoint.response = result + endpoint.response = {...result, isWorking: result.status === 'Success'} endpoint.updated_at = new Date() await nodeService.updateEndpointInfo(endpoint) @@ -255,7 +255,8 @@ const endpointsHealth = async (endpoints, producerId) => { endpoint.time = (new Date() - startTime) / 1000 endpoint.response = { status: response?.status, - statusText: response?.statusText + statusText: response?.statusText, + isWorking: response?.status === StatusCodes.OK } endpoint.head_block_time = nodeInfo?.head_block_time || null endpoint.updated_at = new Date() @@ -267,7 +268,7 @@ const endpointsHealth = async (endpoints, producerId) => { checkedList.push({ ...endpoint, producer_id: producerId, - isWorking: Number(endpoint?.response?.status === StatusCodes.OK) + isWorking: Number(endpoint?.response?.isWorking) }) } } From 2e3a25f5f1398dab4cfd178819e00bbccee550c3 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 6 Jun 2023 15:38:58 -0600 Subject: [PATCH 08/11] chore(webapp): use isWorking attribute from endpoint response --- webapp/src/components/EndpointsTable/index.js | 10 +++++----- webapp/src/components/NodeCard/EndpointsChips.js | 2 +- webapp/src/hooks/customHooks/useEndpointsState.js | 3 +-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/webapp/src/components/EndpointsTable/index.js b/webapp/src/components/EndpointsTable/index.js index 031a100f..a55b589e 100644 --- a/webapp/src/components/EndpointsTable/index.js +++ b/webapp/src/components/EndpointsTable/index.js @@ -52,13 +52,13 @@ const EndpointsTable = ({ producers }) => { const getStatus = endpoint => { if (endpoint.response.status === undefined) return - if (endpoint.response?.status === 'Success') return 'greenLight' + if (endpoint.response?.isWorking) { + return !endpoint.head_block_time || isSynchronized(endpoint) + ? 'greenLight' + : 'timerOff' + } switch (Math.floor(endpoint.response?.status / 100)) { - case 2: - return !endpoint.head_block_time || isSynchronized(endpoint) - ? 'greenLight' - : 'timerOff' case 4: case 5: return 'yellowLight' diff --git a/webapp/src/components/NodeCard/EndpointsChips.js b/webapp/src/components/NodeCard/EndpointsChips.js index db985cbf..0cf7ff39 100644 --- a/webapp/src/components/NodeCard/EndpointsChips.js +++ b/webapp/src/components/NodeCard/EndpointsChips.js @@ -86,7 +86,7 @@ const EndpointsChips = ({ node }) => { break } - if (endpoint?.response?.status !== 200 && endpoint?.response?.status !== 'Success') { + if (!endpoint?.response?.isWorking) { status.failingEndpoints.push(endpoint.type) } diff --git a/webapp/src/hooks/customHooks/useEndpointsState.js b/webapp/src/hooks/customHooks/useEndpointsState.js index 29543c79..eff1e36b 100644 --- a/webapp/src/hooks/customHooks/useEndpointsState.js +++ b/webapp/src/hooks/customHooks/useEndpointsState.js @@ -46,8 +46,7 @@ const useEndpointsState = () => { const handleFilter = useCallback(value => { const filter = value - ? { _or: [{ response: { _contains: { status: 200 } } }, - {response: { _contains: { status: "Success" }}}]} + ? {response: { _contains: { isWorking: true }}} : { value: { _gt: '' } } setPagination(prev => ({ From 236418b933929fea2eb95781b68f3fc394975bde Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 12 Jun 2023 13:26:31 -0600 Subject: [PATCH 09/11] chore(hapi): update stats when updating bp.jsons --- hapi/src/services/producer.service.js | 5 +---- hapi/src/workers/producers.worker.js | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/hapi/src/services/producer.service.js b/hapi/src/services/producer.service.js index ec3a01ba..7ce3168f 100644 --- a/hapi/src/services/producer.service.js +++ b/hapi/src/services/producer.service.js @@ -94,10 +94,7 @@ const syncProducers = async () => { await saveEstimateNextUpdate(new Date()) await syncNodes(producers.slice(0, eosConfig.eosTopLimit)) await syncEndpoints() - - if (!eosConfig.stateHistoryPluginEndpoint) { - await statsService.sync() - } + await statsService.sync() } } diff --git a/hapi/src/workers/producers.worker.js b/hapi/src/workers/producers.worker.js index 99337e42..36863f46 100644 --- a/hapi/src/workers/producers.worker.js +++ b/hapi/src/workers/producers.worker.js @@ -66,7 +66,6 @@ const start = async () => { } if (eosConfig.stateHistoryPluginEndpoint) { - run('SYNC STATS INFO', statsService.sync, workersConfig.syncStatsInterval) run('SYNC BLOCK HISTORY', stateHistoryPluginService.init) run('SYNC MISSED BLOCKS', missedBlocksService.syncMissedBlocks) run('SYNC MISSED BLOCKS PER PRODUCER', statsService.getCurrentMissedBlock) From e8d3701580010792346c356463e6a3db30e9f97f Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 12 Jun 2023 13:42:59 -0600 Subject: [PATCH 10/11] chore(webapp): format code --- .../hooks/customHooks/useEndpointsState.js | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/webapp/src/hooks/customHooks/useEndpointsState.js b/webapp/src/hooks/customHooks/useEndpointsState.js index eff1e36b..ee1f8422 100644 --- a/webapp/src/hooks/customHooks/useEndpointsState.js +++ b/webapp/src/hooks/customHooks/useEndpointsState.js @@ -45,19 +45,17 @@ const useEndpointsState = () => { }, [data]) const handleFilter = useCallback(value => { - const filter = value - ? {response: { _contains: { isWorking: true }}} - : { value: { _gt: '' } } + const filter = value + ? { response: { _contains: { isWorking: true } } } + : { value: { _gt: '' } } - setPagination(prev => ({ - ...prev, - page: 1, - where: { ...prev.where, nodes: { endpoints: filter } }, - endpointFilter: value - ? filter - : undefined, - })) - }, [setPagination]) + setPagination(prev => ({ + ...prev, + page: 1, + where: { ...prev.where, nodes: { endpoints: filter } }, + endpointFilter: value ? filter : undefined, + })) + }, [setPagination]) return [ { loading, pagination, producers: items, filters }, From 46e5ff40f5c05686668a9a7f44f711be068702f0 Mon Sep 17 00:00:00 2001 From: codefactor-io Date: Mon, 12 Jun 2023 19:58:26 +0000 Subject: [PATCH 11/11] [CodeFactor] Apply fixes --- hapi/src/utils/producer.util.js | 13 ++++++++----- webapp/src/routes/EndpointsList/styles.js | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/hapi/src/utils/producer.util.js b/hapi/src/utils/producer.util.js index d8c2ad58..edaff8c6 100644 --- a/hapi/src/utils/producer.util.js +++ b/hapi/src/utils/producer.util.js @@ -11,7 +11,9 @@ const getUrlStatus = async (url, api = '') => { url = url.replace(urlRegex, '') try { - const response = await axiosUtil.instance.get(`${url}${api}`, { timeout: 30000 }) + const response = await axiosUtil.instance.get(`${url}${api}`, { + timeout: 30000 + }) return response } catch (error) { @@ -19,9 +21,9 @@ const getUrlStatus = async (url, api = '') => { } } -const isP2PResponding = async endpoint => { +const isP2PResponding = async (endpoint) => { const splitted = endpoint?.split(':') || {} - const { [0]: host, [1]: port } = splitted + const { 0: host, 1: port } = splitted if (splitted.length !== 2 || !host || !port) return { status: 'Failed', statusText: 'Invalid endpoint format' } @@ -32,7 +34,7 @@ const isP2PResponding = async endpoint => { resolve({ status: 'Success', statusText: 'Connection established' }) }) - client.on('error', err => { + client.on('error', (err) => { let errorMessage = '' switch (Math.abs(err?.errno)) { @@ -70,7 +72,8 @@ const getSupportedAPIs = async (api) => { try { const response = await axiosUtil.instance.get( - `${api}/v1/node/get_supported_apis`, { timeout: 30000 } + `${api}/v1/node/get_supported_apis`, + { timeout: 30000 } ) supportedAPIs = response.data?.apis diff --git a/webapp/src/routes/EndpointsList/styles.js b/webapp/src/routes/EndpointsList/styles.js index 91f5b6b9..739ec412 100644 --- a/webapp/src/routes/EndpointsList/styles.js +++ b/webapp/src/routes/EndpointsList/styles.js @@ -47,7 +47,7 @@ export default (theme) => ({ boxShadow: '0px 1px 5px rgba(0, 0, 0, 0.15) !important', }, noShadow: { - '& .MuiPaper-root':{ + '& .MuiPaper-root': { boxShadow: 'none !important' } }