diff --git a/lib/handlers/injector-sor.ts b/lib/handlers/injector-sor.ts index 81fc90d1c5..4d0e0a5a8a 100644 --- a/lib/handlers/injector-sor.ts +++ b/lib/handlers/injector-sor.ts @@ -31,6 +31,8 @@ import { V3PoolProvider, IRouteCachingProvider, CachingV2PoolProvider, + TokenValidatorProvider, + TokenPropertiesProvider, } from '@uniswap/smart-order-router' import { TokenList } from '@uniswap/token-lists' import { default as bunyan, default as Logger } from 'bunyan' @@ -48,6 +50,7 @@ import { DefaultEVMClient } from './evm/EVMClient' import { InstrumentedEVMProvider } from './evm/provider/InstrumentedEVMProvider' import { deriveProviderName } from './evm/provider/ProviderName' import { V2DynamoCache } from './pools/pool-caching/v2/v2-dynamo-cache' +import { OnChainTokenFeeFetcher } from '@uniswap/smart-order-router/build/main/providers/token-fee-fetcher' export const SUPPORTED_CHAINS: ChainId[] = [ ChainId.MAINNET, @@ -190,7 +193,19 @@ export abstract class InjectorSOR extends Injector< sourceOfTruthPoolProvider: noCacheV3PoolProvider, }) - const underlyingV2PoolProvider = new V2PoolProvider(chainId, multicall2Provider) + const tokenFeeFetcher = new OnChainTokenFeeFetcher(chainId, provider) + const tokenValidatorProvider = new TokenValidatorProvider( + chainId, + multicall2Provider, + new NodeJSCache(new NodeCache({ stdTTL: 30000, useClones: false })) + ) + const tokenPropertiesProvider = new TokenPropertiesProvider( + chainId, + tokenValidatorProvider, + new NodeJSCache(new NodeCache({ stdTTL: 30000, useClones: false })), + tokenFeeFetcher + ) + const underlyingV2PoolProvider = new V2PoolProvider(chainId, multicall2Provider, tokenPropertiesProvider) const v2PoolProvider = new CachingV2PoolProvider( chainId, underlyingV2PoolProvider, diff --git a/lib/handlers/pools/pool-caching/v2/v2-dynamo-cache.ts b/lib/handlers/pools/pool-caching/v2/v2-dynamo-cache.ts index 2f01d66cc5..f870c19ddf 100644 --- a/lib/handlers/pools/pool-caching/v2/v2-dynamo-cache.ts +++ b/lib/handlers/pools/pool-caching/v2/v2-dynamo-cache.ts @@ -1,8 +1,8 @@ import { ICache } from '@uniswap/smart-order-router/build/main/providers/cache' import { Pair } from '@uniswap/v2-sdk' -import { DocumentClient } from 'aws-sdk/clients/dynamodb' -import { log } from '@uniswap/smart-order-router' -import { PairMarshaller } from '../../../marshalling' +import { BatchGetItemInput, DocumentClient } from 'aws-sdk/clients/dynamodb' +import { log, metric, MetricLoggerUnit } from '@uniswap/smart-order-router' +import { MarshalledPair, PairMarshaller } from '../../../marshalling' export class V2DynamoCache implements ICache<{ pair: Pair; block?: number }> { private readonly ddbClient: DocumentClient @@ -18,6 +18,57 @@ export class V2DynamoCache implements ICache<{ pair: Pair; block?: number }> { }, }) } + + // TODO: ROUTE-81 & ROUTE-84 - once smart-order-router updates the ICache.batchGet API to take in + // composite key as part of ROUTE-83, then we can leverage the batchGet Dynamo call + // for both caching-pool-provider and token-properties-provider + // Prior to completion of ROUTE-81 & ROUTE-84, this function is not being called anywhere. + async batchGet(keys: Set): Promise> { + const records: Record = {} + const batchGetParams: BatchGetItemInput = { + RequestItems: { + [this.tableName]: { + Keys: Array.from(keys).map((key) => { + // TODO: ROUTE-83 fix the ICache.batchGet to allow passing in composite key type + // instead of a simple string type + // then fix the key destructuring here + const [cacheKey, block] = key.split(':', 2) + return { + cacheKey: { S: cacheKey }, + block: { N: block }, + } + }), + }, + }, + } + + const result = await this.ddbClient.batchGet(batchGetParams).promise() + const unprocessedKeys = result?.UnprocessedKeys?.[this.tableName]?.Keys + + if (unprocessedKeys && unprocessedKeys.length > 0) { + metric.putMetric('V2_PAIRS_DYNAMO_CACHING_UNPROCESSED_KEYS', unprocessedKeys.length, MetricLoggerUnit.None) + } + + return ( + result.Responses?.[this.tableName] + ?.map((item) => { + const key = item.cacheKey.S! + const block = parseInt(item.block.N!) + const itemBinary = item.item.B! + const pairBuffer = Buffer.from(itemBinary) + const pairJson: MarshalledPair = JSON.parse(pairBuffer.toString()) + + return { + [key]: { + pair: PairMarshaller.unmarshal(pairJson), + block, + }, + } + }) + ?.reduce((accumulatedRecords, currentRecord) => ({ ...accumulatedRecords, ...currentRecord }), records) ?? + records + ) + } async get(key: string): Promise<{ pair: Pair; block?: number } | undefined> { try { const queryParams = { diff --git a/package-lock.json b/package-lock.json index 54590235bd..c16b9e9607 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "@uniswap/permit2-sdk": "^1.2.0", "@uniswap/router-sdk": "^1.6.0", "@uniswap/sdk-core": "^4.0.3", - "@uniswap/smart-order-router": "3.16.21", + "@uniswap/smart-order-router": "3.16.24", "@uniswap/token-lists": "^1.0.0-beta.33", "@uniswap/universal-router-sdk": "^1.5.7", "@uniswap/v2-sdk": "^3.2.0", @@ -4294,9 +4294,9 @@ } }, "node_modules/@uniswap/sdk-core": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@uniswap/sdk-core/-/sdk-core-4.0.6.tgz", - "integrity": "sha512-6GzCVfnOiJtvo91zlF/VjnC2OEbBRThVclzrh7+Zmo8dBovXwSlXwqn3RkSWACn/XEOzAKH70TficfOWm6mWJA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@uniswap/sdk-core/-/sdk-core-4.0.7.tgz", + "integrity": "sha512-jscx7KUIWzQatcL5PHY6xy0gEL9IGQcL5h/obxzX9foP2KoNk9cq66Ia8I2Kvpa7zBcPOeW1hU0hJNBq6CzcIQ==", "dependencies": { "@ethersproject/address": "^5.0.2", "big.js": "^5.2.2", @@ -4310,19 +4310,19 @@ } }, "node_modules/@uniswap/smart-order-router": { - "version": "3.16.21", - "resolved": "https://registry.npmjs.org/@uniswap/smart-order-router/-/smart-order-router-3.16.21.tgz", - "integrity": "sha512-1dHqbv+35efK+WNp2tB0O2obD5C1E18/kKkyqkASHyqiaf8DcyFUqyPa9+VqGZnl2sJkjDUtmKg+qGvYFORPzQ==", + "version": "3.16.24", + "resolved": "https://registry.npmjs.org/@uniswap/smart-order-router/-/smart-order-router-3.16.24.tgz", + "integrity": "sha512-carwL4G4CtGtaj/NQGdMv1Y0ctBcnJeyHKoGbUeyyQltEWL29fxyAUoBZm7Zu85hx5SEJox0VbLSaHdgfcl/lw==", "dependencies": { "@uniswap/default-token-list": "^11.2.0", "@uniswap/permit2-sdk": "^1.2.0", "@uniswap/router-sdk": "^1.6.0", - "@uniswap/sdk-core": "^4.0.6", + "@uniswap/sdk-core": "^4.0.7", "@uniswap/swap-router-contracts": "^1.3.0", "@uniswap/token-lists": "^1.0.0-beta.31", "@uniswap/universal-router": "^1.0.1", "@uniswap/universal-router-sdk": "^1.5.7", - "@uniswap/v2-sdk": "^3.2.0", + "@uniswap/v2-sdk": "^3.2.1", "@uniswap/v3-sdk": "^3.10.0", "async-retry": "^1.3.1", "await-timeout": "^1.1.1", @@ -4481,13 +4481,13 @@ } }, "node_modules/@uniswap/v2-sdk": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@uniswap/v2-sdk/-/v2-sdk-3.2.0.tgz", - "integrity": "sha512-kBOJ6Iwtgb/2LckLMIzfbPM37/ll0F+33lzPmZlqoJwsT0F2hZdVfAhclufZcSb0Y9RdLXl6372CZJ+lhx8cUQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@uniswap/v2-sdk/-/v2-sdk-3.2.1.tgz", + "integrity": "sha512-YocFCG97t7qi0fZrBWjFz3dfOgW+rhVN70PlciwcioG+x3KmQlJH7pVfCA34U/BDVFfebHp/iS/De6ajvMmJBg==", "dependencies": { "@ethersproject/address": "^5.0.0", "@ethersproject/solidity": "^5.0.0", - "@uniswap/sdk-core": "^4.0.2", + "@uniswap/sdk-core": "^4.0.7", "tiny-invariant": "^1.1.0", "tiny-warning": "^1.0.3" }, @@ -27373,9 +27373,9 @@ } }, "@uniswap/sdk-core": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@uniswap/sdk-core/-/sdk-core-4.0.6.tgz", - "integrity": "sha512-6GzCVfnOiJtvo91zlF/VjnC2OEbBRThVclzrh7+Zmo8dBovXwSlXwqn3RkSWACn/XEOzAKH70TficfOWm6mWJA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@uniswap/sdk-core/-/sdk-core-4.0.7.tgz", + "integrity": "sha512-jscx7KUIWzQatcL5PHY6xy0gEL9IGQcL5h/obxzX9foP2KoNk9cq66Ia8I2Kvpa7zBcPOeW1hU0hJNBq6CzcIQ==", "requires": { "@ethersproject/address": "^5.0.2", "big.js": "^5.2.2", @@ -27386,19 +27386,19 @@ } }, "@uniswap/smart-order-router": { - "version": "3.16.21", - "resolved": "https://registry.npmjs.org/@uniswap/smart-order-router/-/smart-order-router-3.16.21.tgz", - "integrity": "sha512-1dHqbv+35efK+WNp2tB0O2obD5C1E18/kKkyqkASHyqiaf8DcyFUqyPa9+VqGZnl2sJkjDUtmKg+qGvYFORPzQ==", + "version": "3.16.24", + "resolved": "https://registry.npmjs.org/@uniswap/smart-order-router/-/smart-order-router-3.16.24.tgz", + "integrity": "sha512-carwL4G4CtGtaj/NQGdMv1Y0ctBcnJeyHKoGbUeyyQltEWL29fxyAUoBZm7Zu85hx5SEJox0VbLSaHdgfcl/lw==", "requires": { "@uniswap/default-token-list": "^11.2.0", "@uniswap/permit2-sdk": "^1.2.0", "@uniswap/router-sdk": "^1.6.0", - "@uniswap/sdk-core": "^4.0.6", + "@uniswap/sdk-core": "^4.0.7", "@uniswap/swap-router-contracts": "^1.3.0", "@uniswap/token-lists": "^1.0.0-beta.31", "@uniswap/universal-router": "^1.0.1", "@uniswap/universal-router-sdk": "^1.5.7", - "@uniswap/v2-sdk": "^3.2.0", + "@uniswap/v2-sdk": "^3.2.1", "@uniswap/v3-sdk": "^3.10.0", "async-retry": "^1.3.1", "await-timeout": "^1.1.1", @@ -27527,13 +27527,13 @@ "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" }, "@uniswap/v2-sdk": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@uniswap/v2-sdk/-/v2-sdk-3.2.0.tgz", - "integrity": "sha512-kBOJ6Iwtgb/2LckLMIzfbPM37/ll0F+33lzPmZlqoJwsT0F2hZdVfAhclufZcSb0Y9RdLXl6372CZJ+lhx8cUQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@uniswap/v2-sdk/-/v2-sdk-3.2.1.tgz", + "integrity": "sha512-YocFCG97t7qi0fZrBWjFz3dfOgW+rhVN70PlciwcioG+x3KmQlJH7pVfCA34U/BDVFfebHp/iS/De6ajvMmJBg==", "requires": { "@ethersproject/address": "^5.0.0", "@ethersproject/solidity": "^5.0.0", - "@uniswap/sdk-core": "^4.0.2", + "@uniswap/sdk-core": "^4.0.7", "tiny-invariant": "^1.1.0", "tiny-warning": "^1.0.3" } diff --git a/package.json b/package.json index 6821507edb..f4afc1147c 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "@uniswap/permit2-sdk": "^1.2.0", "@uniswap/router-sdk": "^1.6.0", "@uniswap/sdk-core": "^4.0.3", - "@uniswap/smart-order-router": "3.16.21", + "@uniswap/smart-order-router": "3.16.24", "@uniswap/token-lists": "^1.0.0-beta.33", "@uniswap/universal-router-sdk": "^1.5.7", "@uniswap/v2-sdk": "^3.2.0",