diff --git a/src/balance/storage.ts b/src/balance/storage.ts index 3f9749937..1ca1ed909 100644 --- a/src/balance/storage.ts +++ b/src/balance/storage.ts @@ -6,17 +6,13 @@ import { Balances } from "./types" /** * @name getBalances - * @summary Get the balances of an account including free & reserved balances as well as the total. + * @summary Get the balances of an account including free & reserved balances as well as the total. * Currently Mainnet also returns miscFrozen & feeFrozen while alphanet returns frozen and flags. After next Mainnet runtime upgrade both miscFrozen & feeFrozen will be removed. * @param address Public address of the account to get balances. * @returns The balances of the account. */ -export const getBalances = async ( - address: string, -): Promise => { - const balances: Balances = ( - (await query(txPallets.system, chainQuery.account, [address])) as any - ).data +export const getBalances = async (address: string): Promise => { + const balances: Balances = ((await query(txPallets.system, chainQuery.account, [address])) as any).data return balances } diff --git a/src/balance/types.ts b/src/balance/types.ts index 25194477d..c5e695649 100644 --- a/src/balance/types.ts +++ b/src/balance/types.ts @@ -1,10 +1,10 @@ import BN from "bn.js" export type Balances = { - free: BN, - reserved: BN, - frozen?: BN, - flags?: BN, - miscFrozen?: BN, - feeFrozen?: BN, + free: BN + reserved: BN + frozen?: BN + flags?: BN + miscFrozen?: BN + feeFrozen?: BN } diff --git a/src/helpers/http.ts b/src/helpers/http.ts index 1cb491d1c..17c105ed6 100644 --- a/src/helpers/http.ts +++ b/src/helpers/http.ts @@ -6,7 +6,7 @@ export class HttpClient { constructor(baseURL: string, timeout?: number) { this.client = axios.create({ baseURL, - ...(timeout && { timeout }) + ...(timeout && { timeout }), }) } diff --git a/src/helpers/tee.ts b/src/helpers/tee.ts index 7e786ffdd..71c435ecc 100644 --- a/src/helpers/tee.ts +++ b/src/helpers/tee.ts @@ -34,6 +34,8 @@ import { ClusterDataType, } from "../tee/types" import { isValidAddress, query } from "../blockchain" +import { getBalances } from "../balance" +import { BN } from "bn.js" export const SSSA_NUMSHARES = 5 export const SSSA_THRESHOLD = 3 @@ -94,15 +96,24 @@ export const combineKeyShares = (shares: string[]): string => { */ export const getEnclaveHealthStatus = async (clusterId = 0, timeout = 10000) => { const teeEnclaves = await getTeeEnclavesBaseUrl(clusterId) + const lastBlock = await getLastBlock() const clusterHealthCheck = await Promise.all( teeEnclaves.map(async (enclaveUrl, idx) => { const http = new HttpClient(ensureHttps(enclaveUrl), timeout) const enclaveData: EnclaveHealthType = await http.getRaw(TEE_HEALTH_ENDPOINT) const isError = enclaveData.status !== 200 - if (isError || !enclaveData.sync_state.length || enclaveData.sync_state == "setup") - throw new Error( - `${Errors.TEE_ENCLAVE_NOT_AVAILBLE} - ID ${idx}, URL: ${enclaveUrl}. ${enclaveData.description}`, - ) + if (isError || !enclaveData.sync_state.length || enclaveData.sync_state == "setup") throw new Error( + `${Errors.TEE_ENCLAVE_NOT_AVAILBLE} - ID ${idx}, URL: ${enclaveUrl}. ${enclaveData.description}`, + ) + // ADDITIONAL CHECKS + if ((lastBlock - enclaveData.block_number) > 4) throw new Error( + `${Errors.TEE_ENCLAVE_NOT_AVAILBLE} - ID ${idx}, URL: ${enclaveUrl}. Enclave blocks not synchornized with chain`, + ) + const { free } = await getBalances(enclaveData.enclave_address) + const ONE_CAPS = new BN("1000000000000000000") + if (free.lt(ONE_CAPS)) throw new Error( + `${Errors.TEE_ENCLAVE_NOT_AVAILBLE} - ID ${idx}, URL: ${enclaveUrl}. Enclave balance too low`, + ) return enclaveData }), ) @@ -223,16 +234,15 @@ export const getPublicsClusters = async () => { */ export const getFirstPublicClusterAvailable = async (timeout = 10000) => { const publicClusters = await getPublicsClusters() - if (publicClusters.length === 0) return undefined; + if (publicClusters.length === 0) return undefined for (const cluster of publicClusters) { try { - const healthData = await timeoutTrigger(() => - getEnclaveDataAndHealth(cluster, timeout), + const healthData = await timeoutTrigger(() => + getEnclaveHealthStatus(cluster, timeout), timeout + 1000 ) - const filteredData = healthData.filter((c) => c.status === 200) - if (filteredData.length === ENCLAVES_IN_CLUSTER) { + if (healthData.length === ENCLAVES_IN_CLUSTER) { return cluster } } catch (error) { @@ -630,4 +640,4 @@ export const teeNFTReconciliation = async ( if (!nftList) throw new Error(Errors.NFT_RECONCILIATION_FAILED) nftList = nftList.filter((x) => x !== undefined) return [...nftList, ...errors] -} \ No newline at end of file +} diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index 5e56fb95e..200ccb8f6 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -74,17 +74,16 @@ export const ensureHttps = (url: string) => { export const timeoutTrigger = (fn: () => Promise, duration = 10000): Promise => { return new Promise((resolve, reject) => { const timer = setTimeout(() => { - reject(new Error('Error: Function timed out')); - }, duration); + reject(new Error("Error: Function timed out")) + }, duration) try { - const data = fn(); - clearTimeout(timer); - resolve(data); + const data = fn() + clearTimeout(timer) + resolve(data) } catch (error) { - clearTimeout(timer); - reject(error); + clearTimeout(timer) + reject(error) } - }); + }) } -