From cda515531fea23401fa34139c0b9e0a0dc451943 Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 2 Dec 2024 11:24:09 +0100 Subject: [PATCH] feat: caching experiment --- scripts/clients.ts | 48 +++++++++++++++++++++++++++++++++--- scripts/generateAddresses.ts | 2 ++ src/ts/AaveV3Ethereum.ts | 3 ++- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/scripts/clients.ts b/scripts/clients.ts index c36bb40f..0ca27e57 100644 --- a/scripts/clients.ts +++ b/scripts/clients.ts @@ -1,4 +1,4 @@ -import {HttpTransportConfig, createClient, http} from 'viem'; +import {HttpTransportConfig, createClient, http, custom} from 'viem'; import {Client} from 'viem'; import {ChainList, getRPCUrl} from '@bgd-labs/rpc-env'; @@ -7,15 +7,55 @@ const batchConfig = {batch: {multicall: true}}; const clientCache: Record = {}; +const set = (obj, path, value) => { + // Regex explained: https://regexr.com/58j0k + const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g); + + pathArray.reduce((acc, key, i) => { + if (acc[key] === undefined) acc[key] = {}; + if (i === pathArray.length - 1) acc[key] = value; + return acc[key]; + }, obj); +}; + +export const rpcResponseCache = {}; + +/** + * This client is a custom proxy which will fetch data once and store it forever + * @param chainId + * @returns + */ export function getClient(chainId: number) { if (!clientCache[chainId]) { const rpcURL = getRPCUrl(chainId as any, {alchemyKey: process.env.ALCHEMY_API_KEY}); - - clientCache[chainId] = createClient({ + const transport = http(rpcURL, commonConfig); + const client = createClient({ chain: ChainList[chainId], - transport: http(rpcURL, commonConfig), + transport: transport, ...batchConfig, }); + + const proxy = new Proxy(client, { + get(target, p, receiver) { + const origMethod = Reflect.get(target, p, receiver); + + if (typeof origMethod === 'function') + return async function (...args) { + const cache = rpcResponseCache[chainId]?.[JSON.stringify(args)]; + if (cache) { + console.log('cache hit'); + return cache; + } + + const result = await origMethod.apply(this, args); + set(rpcResponseCache, [chainId, JSON.stringify(args)], result); + return result; + }; + return Reflect.get(target, p, receiver); + }, + }); + + clientCache[chainId] = proxy; } return clientCache[chainId]; } diff --git a/scripts/generateAddresses.ts b/scripts/generateAddresses.ts index cf52048d..6d3cfc5d 100644 --- a/scripts/generateAddresses.ts +++ b/scripts/generateAddresses.ts @@ -64,6 +64,7 @@ import {zkSyncAddresses} from './configs/networks/zksync'; import {ghoArbitrum} from './configs/gho/arbitrum'; import {ghoEthereum} from './configs/gho/ethereum'; import {generateGho} from './generator/ghoGenerator'; +import {rpcResponseCache} from './clients'; async function main() { // cleanup ts artifacts @@ -184,6 +185,7 @@ async function main() { writeFileSync(`./src/ts/AaveAddressBook.ts`, prefixWithGeneratedWarning('')); jsExports.map((jsExport) => appendFileSync('./src/ts/AaveAddressBook.ts', `${jsExport}\n`)); console.log('✅ Generation finished'); + console.log(rpcResponseCache); } main(); diff --git a/src/ts/AaveV3Ethereum.ts b/src/ts/AaveV3Ethereum.ts index 2f1bc3dc..c2439f78 100644 --- a/src/ts/AaveV3Ethereum.ts +++ b/src/ts/AaveV3Ethereum.ts @@ -486,9 +486,10 @@ export const E_MODES = { label: 'sUSDe Stablecoins', collateralBitmap: '4294967296', collateralAssets: ['0x9D39A5DE30e57443BfF2A8307A4256c8797A3497'], - borrowableBitmap: '34359738376', + borrowableBitmap: '34359738632', borrowableAssets: [ '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + '0xdAC17F958D2ee523a2206206994597C13D831ec7', '0xdC035D45d973E3EC169d2276DDab16f1e407384F', ], ltv: 9000,