From a3398cd756863442ea86ba6521670a722073b93c Mon Sep 17 00:00:00 2001 From: Xipu Li Date: Mon, 11 Jul 2022 12:30:52 -0700 Subject: [PATCH 1/2] Filter out zeroRates and fallbackConstantRates --- src/rates.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/rates.ts b/src/rates.ts index bfb0788b..8f10d848 100644 --- a/src/rates.ts +++ b/src/rates.ts @@ -116,7 +116,8 @@ const sanitizeNewRates = ( const getRatesFromProviders = async ( rateObj: ReturnGetRate, - edgeAssetMap: DbDoc + edgeAssetMap: DbDoc, + excludedProviders: string[] = [] ): Promise => { const currentTime = normalizeDate(new Date().toISOString()) if (typeof currentTime !== 'string') throw new Error('malformed date') @@ -140,7 +141,10 @@ const getRatesFromProviders = async ( if (constantCurrencyCodes == null) ({ constantCurrencyCodes = {} } = edgeAssetMap) - for (const provider of rateProviders) { + const eligibleProviders = rateProviders.filter( + provider => !excludedProviders.includes(provider.name) + ) + for (const provider of eligibleProviders) { const remainingRequests = getNullRateArray(rateObj.data) if (remainingRequests.length === 0) break @@ -196,7 +200,8 @@ export const getExchangeRates = async ( const out = await getRatesFromProviders( { data, documents: documents.slice(1) }, - documents[0] + documents[0], + ['zeroRates', 'fallbackConstantRates'] ) const redisPromises: Array> = [] From 42a55fee3df1bd0772b52a13517de8794099faf4 Mon Sep 17 00:00:00 2001 From: Xipu Li Date: Tue, 19 Jul 2022 13:52:38 -0700 Subject: [PATCH 2/2] fixup! Filter out zeroRates and fallbackConstantRates --- src/exchangeRateRouter.ts | 76 +++++++++++++++++++++++++++++++++++++-- src/rates.ts | 17 ++------- 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/exchangeRateRouter.ts b/src/exchangeRateRouter.ts index 8c00a86f..6f3ce08c 100644 --- a/src/exchangeRateRouter.ts +++ b/src/exchangeRateRouter.ts @@ -5,9 +5,20 @@ import nano from 'nano' import promisify from 'promisify-node' import { config } from './config' -import { asReturnGetRate, getExchangeRates } from './rates' -import { hmgetAsync } from './uidEngine' +import { + fallbackConstantRates, + zeroRates +} from './providers/hardcodedProviders' +import { + asReturnGetRate, + AssetMap, + getExchangeRates, + NewRates, + ReturnRate +} from './rates' +import { hgetallAsync, hmgetAsync } from './uidEngine' import { asExtendedReq } from './utils/asExtendedReq' +import currencyCodeMaps from './utils/currencyCodeMaps.json' import { DbDoc } from './utils/dbUtils' import { addIso, @@ -302,6 +313,59 @@ const sendExchangeRates: express.RequestHandler = (req, res, next): void => { res.json({ data: exReq.requestedRatesResult.data }) } +/** + * Produces an Express request handler to be used as a middleware. The + * handler will get rates from the provider and store them in + * `req.requestedRatesResult.data`. + * + * @remarks + * Currenlty, this function is used to query rates from + * {@link zeroRates} and {@link fallbackConstantRates} providers. The + * returned middleware for `zeroRates` will be used before + * {@link queryRedis} and `fallbackConstantRates` after + * {@link queryExchangeRates} so that + * the rates won't be stored in redis and couchdb. + * + * @param provider The provider function that will return a NewRates + * object + * @returns An Express request handler to be used as a middleware. + */ +const queryRatesFromProvder = ( + provider: ( + rateObj: ReturnRate[], + currentTime: string, + assetMap: AssetMap + ) => NewRates +): express.RequestHandler => async (req, res, next): Promise => { + const rateReq = req as ExpressRequest + if (rateReq?.requestedRatesResult == null) return next(500) + + const currentTime = normalizeDate(new Date().toISOString()) + if (typeof currentTime !== 'string') throw new Error('malformed date') + + let constantCurrencyCodes = await hgetallAsync('constantCurrencyCodes') + if (constantCurrencyCodes == null) + constantCurrencyCodes = JSON.parse(currencyCodeMaps.toString()) + + const result = provider( + rateReq.requestedRatesResult?.data ?? [], + currentTime, + constantCurrencyCodes + ) + + for (const date of Object.keys(result)) { + const pairs = result[date] + for (const pair of Object.keys(pairs)) { + rateReq.requestedRatesResult.data.push({ + currency_pair: pair, + date, + exchangeRate: pairs[pair] + }) + } + } + next() +} + // *** ROUTES *** export const exchangeRateRouterV1 = (): express.Router => { @@ -311,8 +375,10 @@ export const exchangeRateRouterV1 = (): express.Router => { exchangeRateCleaner, v1IsoChecker, v1ExchangeRateIsoAdder, + queryRatesFromProvder(zeroRates), queryRedis, queryExchangeRates, + queryRatesFromProvder(fallbackConstantRates), v1ExchangeRateIsoSubtractor, sendExchangeRate ]) @@ -321,8 +387,10 @@ export const exchangeRateRouterV1 = (): express.Router => { exchangeRatesCleaner, v1IsoChecker, v1ExchangeRateIsoAdder, + queryRatesFromProvder(zeroRates), queryRedis, queryExchangeRates, + queryRatesFromProvder(fallbackConstantRates), v1ExchangeRateIsoSubtractor, sendExchangeRates ]) @@ -335,15 +403,19 @@ export const exchangeRateRouterV2 = (): express.Router => { router.get('/exchangeRate', [ exchangeRateCleaner, + queryRatesFromProvder(zeroRates), queryRedis, queryExchangeRates, + queryRatesFromProvder(fallbackConstantRates), sendExchangeRate ]) router.post('/exchangeRates', [ exchangeRatesCleaner, + queryRatesFromProvder(zeroRates), queryRedis, queryExchangeRates, + queryRatesFromProvder(fallbackConstantRates), sendExchangeRates ]) diff --git a/src/rates.ts b/src/rates.ts index 8f10d848..59724ed3 100644 --- a/src/rates.ts +++ b/src/rates.ts @@ -19,10 +19,6 @@ import { coinMarketCap } from './providers/coinMarketCap' import { coinmonitor } from './providers/coinmonitor' import { compound } from './providers/compound' import { currencyConverter } from './providers/currencyConverter' -import { - fallbackConstantRates, - zeroRates -} from './providers/hardcodedProviders' import { nomics } from './providers/nomics' import { openExchangeRates } from './providers/openExchangeRates' import { wazirx } from './providers/wazirx' @@ -116,15 +112,13 @@ const sanitizeNewRates = ( const getRatesFromProviders = async ( rateObj: ReturnGetRate, - edgeAssetMap: DbDoc, - excludedProviders: string[] = [] + edgeAssetMap: DbDoc ): Promise => { const currentTime = normalizeDate(new Date().toISOString()) if (typeof currentTime !== 'string') throw new Error('malformed date') // Retrieve new rates const rateProviders = [ - zeroRates, coinmonitor, wazirx, coingecko, @@ -132,7 +126,6 @@ const getRatesFromProviders = async ( coinMarketCap, nomics, compound, - fallbackConstantRates, currencyConverter, openExchangeRates ] @@ -141,10 +134,7 @@ const getRatesFromProviders = async ( if (constantCurrencyCodes == null) ({ constantCurrencyCodes = {} } = edgeAssetMap) - const eligibleProviders = rateProviders.filter( - provider => !excludedProviders.includes(provider.name) - ) - for (const provider of eligibleProviders) { + for (const provider of rateProviders) { const remainingRequests = getNullRateArray(rateObj.data) if (remainingRequests.length === 0) break @@ -200,8 +190,7 @@ export const getExchangeRates = async ( const out = await getRatesFromProviders( { data, documents: documents.slice(1) }, - documents[0], - ['zeroRates', 'fallbackConstantRates'] + documents[0] ) const redisPromises: Array> = []