Skip to content

Commit

Permalink
chore: bump sor to 4.7.5 - fix: cached routes cache invalidation (#869)
Browse files Browse the repository at this point in the history
* sor 4.7.1 from local

* fix: we roll out new cached routes fix with percent

* fix: we roll out new cached routes fix with percent

* add more comments on per-chain rollout percent

* fix injector.ts to pass in alpha-router params

* make BLOCKS_TO_LIVE to index key on ChainId enum

* remove filter expired cached routes

* 10 minutes blocks-to-live for every chain

* INTENT enum

* npm install SOR

* sdk-core 5.9.0

* fix cachedRoutesCacheInvalidationFixRolloutPercentage

* fix v4PoolParams

* do not tap compare during caching intent quote handler

* 1 hour cached routes refresh
  • Loading branch information
jsy1218 authored Oct 29, 2024
1 parent e75ef26 commit 1f99389
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 69 deletions.
14 changes: 11 additions & 3 deletions lib/handlers/injector-sor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import {
emptyV4FeeTickSpacingsHookAddresses,
EXTRA_V4_FEE_TICK_SPACINGS_HOOK_ADDRESSES,
} from '../util/extraV4FeeTiersTickSpacingsHookAddresses'
import { NEW_CACHED_ROUTES_ROLLOUT_PERCENT } from '../util/newCachedRoutesRolloutPercent'

export const SUPPORTED_CHAINS: ChainId[] = [
ChainId.MAINNET,
Expand Down Expand Up @@ -144,6 +145,10 @@ export type ContainerDependencies = {
tokenValidatorProvider: TokenValidatorProvider
tokenPropertiesProvider: ITokenPropertiesProvider
v2Supported: ChainId[]
v4Supported?: ChainId[]
mixedSupported?: ChainId[]
v4PoolParams?: Array<[number, number, string]>
cachedRoutesCacheInvalidationFixRolloutPercentage?: number
}

export interface ContainerInjected {
Expand Down Expand Up @@ -297,7 +302,7 @@ export abstract class InjectorSOR<Router, QueryParams> extends Injector<
underlyingV2PoolProvider,
new V2DynamoCache(V2_PAIRS_CACHE_TABLE_NAME!)
)
const v4PoolsParams = getApplicableV4FeesTickspacingsHooks(chainId).concat(
const v4PoolParams = getApplicableV4FeesTickspacingsHooks(chainId).concat(
EXTRA_V4_FEE_TICK_SPACINGS_HOOK_ADDRESSES[chainId] ?? emptyV4FeeTickSpacingsHookAddresses
)

Expand All @@ -316,7 +321,7 @@ export abstract class InjectorSOR<Router, QueryParams> extends Injector<
POOL_CACHE_BUCKET_3!,
POOL_CACHE_GZIP_KEY!,
v4PoolProvider,
v4PoolsParams
v4PoolParams
)) as V4AWSSubgraphProvider,
(await this.instantiateSubgraphProvider(
chainId,
Expand Down Expand Up @@ -487,6 +492,8 @@ export abstract class InjectorSOR<Router, QueryParams> extends Injector<

const mixedSupported = [ChainId.MAINNET, ChainId.SEPOLIA, ChainId.GOERLI]

const cachedRoutesCacheInvalidationFixRolloutPercentage = NEW_CACHED_ROUTES_ROLLOUT_PERCENT[chainId]

return {
chainId,
dependencies: {
Expand Down Expand Up @@ -520,7 +527,8 @@ export abstract class InjectorSOR<Router, QueryParams> extends Injector<
v2Supported,
v4Supported,
mixedSupported,
v4PoolsParams,
v4PoolParams,
cachedRoutesCacheInvalidationFixRolloutPercentage,
},
}
})
Expand Down
8 changes: 8 additions & 0 deletions lib/handlers/quote/injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ export class QuoteHandlerInjector extends InjectorSOR<
simulator,
routeCachingProvider,
v2Supported,
v4Supported,
mixedSupported,
v4PoolParams,
cachedRoutesCacheInvalidationFixRolloutPercentage,
} = dependencies[chainIdEnum]!

let onChainQuoteProvider = dependencies[chainIdEnum]!.onChainQuoteProvider
Expand Down Expand Up @@ -135,6 +139,10 @@ export class QuoteHandlerInjector extends InjectorSOR<
tokenValidatorProvider,
tokenPropertiesProvider,
v2Supported,
v4Supported,
mixedSupported,
v4PoolParams,
cachedRoutesCacheInvalidationFixRolloutPercentage,
})
break
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
CachedRoutes,
CacheMode,
ID_TO_NETWORK_NAME,
INTENT,
IRouteCachingProvider,
log,
metric,
Expand All @@ -16,6 +17,7 @@ import { Protocol } from '@uniswap/router-sdk'
import { PairTradeTypeChainId } from './model/pair-trade-type-chain-id'
import { CachedRoutesMarshaller } from '../../marshalling/cached-routes-marshaller'
import { PromiseResult } from 'aws-sdk/lib/request'
import { DEFAULT_BLOCKS_TO_LIVE_ROUTES_DB } from '../../../util/defaultBlocksToLiveRoutesDB'

interface ConstructorParams {
/**
Expand Down Expand Up @@ -43,43 +45,6 @@ export class DynamoRouteCachingProvider extends IRouteCachingProvider {
private readonly ROUTES_DB_TTL = 24 * 60 * 60 // 24 hours
private readonly ROUTES_DB_FLAG_TTL = 2 * 60 // 2 minutes

// heuristic is within 30 seconds we find a route.
// we know each chain block time
// divide those two
private readonly DEFAULT_BLOCKS_TO_LIVE_ROUTES_DB = (chainId: ChainId) => {
switch (chainId) {
// https://dune.com/queries/2138021
case ChainId.ARBITRUM_ONE:
return 100

// https://dune.com/queries/2009572
case ChainId.BASE:
case ChainId.OPTIMISM:
return 60

// https://snowtrace.io/chart/blocktime
case ChainId.AVALANCHE:
return 15

// https://dune.com/KARTOD/blockchains-analysis
case ChainId.BNB:
return 10

// https://dune.com/KARTOD/blockchains-analysis
case ChainId.POLYGON:
return 15

// https://explorer.celo.org/mainnet/
case ChainId.CELO:
return 6

// https://dune.com/KARTOD/blockchains-analysis
case ChainId.MAINNET:
default:
return 2
}
}
// For the Ratio we are approximating Phi (Golden Ratio) by creating a fraction with 2 consecutive Fibonacci numbers
private readonly ROUTES_DB_BUCKET_RATIO: Fraction = new Fraction(514229, 317811)
private readonly ROUTES_TO_TAKE_FROM_ROUTES_DB = 8
private readonly BLOCKS_DIFF_BETWEEN_CACHING_QUOTES: Map<ChainId, number> = new Map([[ChainId.MAINNET, 3]])
Expand Down Expand Up @@ -114,7 +79,7 @@ export class DynamoRouteCachingProvider extends IRouteCachingProvider {
* @protected
*/
protected async _getBlocksToLive(cachedRoutes: CachedRoutes, _: CurrencyAmount<Currency>): Promise<number> {
return this.DEFAULT_BLOCKS_TO_LIVE_ROUTES_DB(cachedRoutes.chainId)
return DEFAULT_BLOCKS_TO_LIVE_ROUTES_DB[cachedRoutes.chainId]
}

/**
Expand Down Expand Up @@ -342,7 +307,7 @@ export class DynamoRouteCachingProvider extends IRouteCachingProvider {
amount: amount.quotient.toString(),
type: partitionKey.tradeType === 0 ? 'exactIn' : 'exactOut',
protocols: protocols.map((protocol) => protocol.toLowerCase()).join(','),
intent: 'caching',
intent: INTENT.CACHING,
requestSource: 'routing-api',
},
}
Expand Down Expand Up @@ -475,14 +440,10 @@ export class DynamoRouteCachingProvider extends IRouteCachingProvider {
_blockNumber: number,
_optimistic: boolean
): CachedRoutes | undefined {
// if it's on sepolia, then we want to filter expired routes by blocks to live
// this is to unblock v4 routing tests on sepolia
if (cachedRoutes?.chainId === ChainId.SEPOLIA) {
return cachedRoutes?.notExpired(_blockNumber, _optimistic) ? cachedRoutes : undefined
} else {
// otherwise, we keep it here, but we need a better plan for how to fix filtering expired cached routes
return cachedRoutes
}
// we can revert it back to never filter expired cached routes in read path
// we will use blocks-to-live in the write cached routes path
// also we can verify that cached routes cache invalidation bug error is gone in sepolia, as we removed hardcoding for sepolia
return cachedRoutes
}

/**
Expand Down
8 changes: 7 additions & 1 deletion lib/handlers/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ChainId, Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import {
AlphaRouterConfig,
CacheMode,
INTENT,
LowerCaseStringArray,
MapWithLowerCaseKey,
ProtocolPoolSelection,
Expand Down Expand Up @@ -238,6 +239,7 @@ export const QUOTE_SPEED_CONFIG: { [key: string]: QuoteSpeedConfig } = {
}

export type IntentSpecificConfig = {
intent?: INTENT
useCachedRoutes?: boolean
overwriteCacheMode?: CacheMode
optimisticCachedRoutes?: boolean
Expand All @@ -246,23 +248,27 @@ export type IntentSpecificConfig = {
export const INTENT_SPECIFIC_CONFIG: { [key: string]: IntentSpecificConfig } = {
caching: {
// When the intent is to create a cache entry, we will use cachedRoutes with Tapcompare to track accuracy
intent: INTENT.CACHING,
useCachedRoutes: true,
overwriteCacheMode: CacheMode.Tapcompare,
// overwriteCacheMode: CacheMode.Tapcompare,
// This optimistic=false is *super* important to avoid an infinite loop of caching quotes calling themselves
optimisticCachedRoutes: false,
},
quote: {
// When the intent is to get a quote, we should use the cache and optimistic cached routes
intent: INTENT.QUOTE,
useCachedRoutes: true,
optimisticCachedRoutes: true,
},
swap: {
// When the intent is to prepare the swap, we can use cache, but it should not be optimistic
intent: INTENT.SWAP,
useCachedRoutes: true,
optimisticCachedRoutes: false,
},
pricing: {
// When the intent is to get pricing, we should use the cache and optimistic cached routes
intent: INTENT.PRICING,
useCachedRoutes: true,
optimisticCachedRoutes: true,
},
Expand Down
48 changes: 48 additions & 0 deletions lib/util/defaultBlocksToLiveRoutesDB.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ChainId } from '@uniswap/sdk-core'

// This is not being used in production today anyway, due to below filterExpiredCachedRoutes method not really filtering on the blocks-to-live
// heuristic is initially within 30 seconds we find a route. (but we are changing to every 1 hour now)
// For the Ratio we are approximating Phi (Golden Ratio) by creating a fraction with 2 consecutive Fibonacci numbers

// changing to this way with ChainId enum as key indexing, so that we wont forgot to add new chain tuned blocks-to-live
// those are only gonna be enabled with DynamoRouteCachingProvider.newCachedRoutesRolloutPercent anyway
export const DEFAULT_BLOCKS_TO_LIVE_ROUTES_DB: { [chain in ChainId]: number } = {
// (60 minutes) / (12 seconds)= 300
[ChainId.MAINNET]: 300,
[ChainId.GOERLI]: 300,
[ChainId.SEPOLIA]: 300,
// (60 minutes) / (2 seconds) = 1800
[ChainId.OPTIMISM]: 1800,
[ChainId.OPTIMISM_GOERLI]: 1800,
[ChainId.OPTIMISM_SEPOLIA]: 1800,
[ChainId.BASE]: 1800,
[ChainId.ZORA]: 1800,
[ChainId.BASE_GOERLI]: 1800,
[ChainId.ZORA_SEPOLIA]: 1800,
[ChainId.BLAST]: 1800,
[ChainId.WORLDCHAIN]: 1800,
// (60 minutes) / (1 seconds) = 3600
[ChainId.ASTROCHAIN_SEPOLIA]: 3600,
// (60 minutes) / (250 milliseconds) = 14400
[ChainId.ARBITRUM_ONE]: 14400,
[ChainId.ARBITRUM_GOERLI]: 14400,
[ChainId.ARBITRUM_SEPOLIA]: 14400,
// (60 minutes) / (2 seconds) = 1800
[ChainId.POLYGON]: 1800,
[ChainId.POLYGON_MUMBAI]: 1800,
// (60 minutes) / (5 seconds) = 720
[ChainId.CELO]: 720,
[ChainId.CELO_ALFAJORES]: 720,
// (60 minutes) / (5 seconds) = 720
[ChainId.GNOSIS]: 720,
// (60 minutes) / (6 seconds) = 600
[ChainId.MOONBEAM]: 600,
// (60 minutes) / (3 seconds) = 1200
[ChainId.BNB]: 1200,
// (60 minutes) / (3 seconds) = 1200
[ChainId.AVALANCHE]: 1200,
// (60 minutes) / (33 seconds) = 148
[ChainId.ROOTSTOCK]: 148,
// (60 minutes) / (1 seconds) = 3600
[ChainId.ZKSYNC]: 3600,
}
34 changes: 34 additions & 0 deletions lib/util/newCachedRoutesRolloutPercent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ChainId } from '@uniswap/sdk-core'

// percent is between 0% - 100%, defined in SOR
// testnets all go to 100% directly
// production nets depending on revenue/quote traffic volume, if it's medium/high 1%, otherwise super low traffic (< 100 quotes per 5 minutes) 100%
// so zora and blast go to 100% directly. rootstock is not supported by uniswap labs product or protocol layer, go to 100% directly.
export const NEW_CACHED_ROUTES_ROLLOUT_PERCENT: { [chain in ChainId]: number } = {
[ChainId.MAINNET]: 1,
[ChainId.GOERLI]: 100,
[ChainId.SEPOLIA]: 100,
[ChainId.OPTIMISM]: 1,
[ChainId.OPTIMISM_GOERLI]: 100,
[ChainId.OPTIMISM_SEPOLIA]: 100,
[ChainId.ARBITRUM_ONE]: 1,
[ChainId.ARBITRUM_GOERLI]: 100,
[ChainId.ARBITRUM_SEPOLIA]: 100,
[ChainId.POLYGON]: 1,
[ChainId.POLYGON_MUMBAI]: 100,
[ChainId.CELO]: 1,
[ChainId.CELO_ALFAJORES]: 100,
[ChainId.GNOSIS]: 1,
[ChainId.MOONBEAM]: 1,
[ChainId.BNB]: 1,
[ChainId.AVALANCHE]: 1,
[ChainId.BASE_GOERLI]: 100,
[ChainId.BASE]: 1,
[ChainId.ZORA]: 100,
[ChainId.ZORA_SEPOLIA]: 100,
[ChainId.ROOTSTOCK]: 100,
[ChainId.BLAST]: 100,
[ChainId.ZKSYNC]: 1,
[ChainId.WORLDCHAIN]: 1,
[ChainId.ASTROCHAIN_SEPOLIA]: 100,
}
32 changes: 16 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@
"@uniswap/default-token-list": "^11.13.0",
"@uniswap/permit2-sdk": "^1.3.0",
"@uniswap/router-sdk": "^1.14.0",
"@uniswap/sdk-core": "^5.8.5",
"@uniswap/sdk-core": "^5.9.0",
"@types/semver": "^7.5.8",
"@uniswap/smart-order-router": "4.7.3",
"@uniswap/smart-order-router": "4.7.5",
"@uniswap/token-lists": "^1.0.0-beta.33",
"@uniswap/universal-router-sdk": "^4.6.1",
"@uniswap/v2-sdk": "^4.6.1",
Expand Down

0 comments on commit 1f99389

Please sign in to comment.