From 17db74fc5265487eace4854c0e7558c845d67624 Mon Sep 17 00:00:00 2001 From: Derek Date: Sat, 9 Mar 2024 16:08:00 -0800 Subject: [PATCH] cache last 100k block queries quantized by blockStep --- app/api/packets/route.ts | 22 +++++++++++++++------- app/api/utils/provider-cache.ts | 13 +++++++++---- app/utils/chains/configs.ts | 4 +++- app/utils/types/chain.ts | 1 + 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/app/api/packets/route.ts b/app/api/packets/route.ts index 0c3187e..7d0eb71 100644 --- a/app/api/packets/route.ts +++ b/app/api/packets/route.ts @@ -46,8 +46,7 @@ export async function GET(request: NextRequest) { validChannelIds.add(channel.channelId); }); - const fromBlock = Number(from); - const toBlock = to ? Number(to) : 'latest'; + const blockStep = 30; // Collect send logs from all chains let sendLogs: Array<[ethers.EventLog, CHAIN]> = []; @@ -55,16 +54,19 @@ export async function GET(request: NextRequest) { CHAIN, CachingJsonRpcProvider >; + let srcChainHeights: Record = {} as Record; let srcChainContracts: Array<[ethers.Contract, CHAIN]> = []; for (const chain in CHAIN_CONFIGS) { const chainId = chain as CHAIN; const dispatcherAddresses = CHAIN_CONFIGS[chainId].dispatchers; const provider = new CachingJsonRpcProvider( CHAIN_CONFIGS[chainId].rpc, - CHAIN_CONFIGS[chainId].id + CHAIN_CONFIGS[chainId].id, + CHAIN_CONFIGS[chainId].cache ); srcChainProviders[chainId] = provider; - let latestBlock = await provider.getBlockNumber(); + const latestBlock = await provider.getBlockNumber(); + srcChainHeights[chainId] = latestBlock - (latestBlock % blockStep); for (const dispatcherAddress of dispatcherAddresses) { const contract = new ethers.Contract( @@ -76,8 +78,9 @@ export async function GET(request: NextRequest) { srcChainContracts.push([contract, chainId]); // query the last 100000 blocks ~2.5 days - let fromBlock = latestBlock - 100000; - let toBlock = latestBlock; + const toBlock = srcChainHeights[chainId]; + const fromBlock = toBlock > 100000 ? toBlock - 100000 : 1; + console.log(`SendPacket fromBlock: ${fromBlock}, toBlock: ${toBlock}`); const newSendLogs = (await contract.queryFilter( 'SendPacket', @@ -157,6 +160,10 @@ export async function GET(request: NextRequest) { // Start by searching for ack events on the source chains const ackLogsPromises = srcChainContracts.map(async ([contract, chain]) => { + const toBlock = srcChainHeights[chain]; + const fromBlock = toBlock > 100000 ? toBlock - 100000 : 1; + + console.log(`Ack fromBlock: ${fromBlock}, toBlock: ${toBlock}`); const newAckLogs = (await contract.queryFilter( 'Acknowledgement', fromBlock, @@ -215,7 +222,8 @@ export async function GET(request: NextRequest) { for (const dispatcherAddress of dispatcherAddresses) { const provider = new CachingJsonRpcProvider( CHAIN_CONFIGS[chainId].rpc, - CHAIN_CONFIGS[chainId].id + CHAIN_CONFIGS[chainId].id, + CHAIN_CONFIGS[chainId].cache ); destChainProviders[chainId] = provider; const contract = new ethers.Contract( diff --git a/app/api/utils/provider-cache.ts b/app/api/utils/provider-cache.ts index c3f9e08..46f9244 100644 --- a/app/api/utils/provider-cache.ts +++ b/app/api/utils/provider-cache.ts @@ -4,9 +4,13 @@ import * as flatCache from 'flat-cache'; export class CachingJsonRpcProvider extends ethers.JsonRpcProvider { private cache; - constructor(url: string, network?: ethers.Networkish) { + constructor( + url: string, + network?: ethers.Networkish, + cache: string = '/tmp' + ) { super(url, network); - this.cache = flatCache.load('ethCache', '/tmp'); + this.cache = flatCache.load('ethCache', cache); } private async fetchDataWithCache( @@ -16,7 +20,6 @@ export class CachingJsonRpcProvider extends ethers.JsonRpcProvider { // Check if the data is already in the cache const cachedData = this.cache.getKey(cacheKey); if (cachedData) { - console.log('CACHE HIT: ', cacheKey); return cachedData; } @@ -53,7 +56,9 @@ export class CachingJsonRpcProvider extends ethers.JsonRpcProvider { async getLogs(filter: ethers.Filter): Promise> { return await this.fetchDataWithCache( - `${this._network.chainId}_logs_${filter.address}_${filter.fromBlock}_${filter.toBlock}`, + `${this._network.chainId}_logs_${filter.topics![0]!.toString()}_${ + filter.address + }_${filter.fromBlock}_${filter.toBlock}`, async () => await super.getLogs(filter) ); } diff --git a/app/utils/chains/configs.ts b/app/utils/chains/configs.ts index d78fff3..ad631fe 100644 --- a/app/utils/chains/configs.ts +++ b/app/utils/chains/configs.ts @@ -7,7 +7,7 @@ let opDispatcher = process.env.DISPATCHER_ADDRESS_OPTIMISM!; let baseDispatcher = process.env.DISPATCHER_ADDRESS_BASE!; let opDispatcherSimClient = process.env.DISPATCHER_ADDRESS_OPTIMISM_SIMCLIENT!; let baseDispatcherSimClient = process.env.DISPATCHER_ADDRESS_BASE_SIMCLIENT!; - +let cachePath = process.env.CACHE_PATH || '/cache'; let optimismRPC = process.env.OPTIMISM_RPC || 'https://opt-sepolia.g.alchemy.com/v2/iMhzwCPw18v9Byeh59cedtUKbul_jFF3'; // "https://opt-sepolia.g.alchemy.com/v2/jKvLhhXvtnWdNeZrKst0demxnwJcYH1o" @@ -25,6 +25,7 @@ export const CHAIN_CONFIGS: { dispatchers: [opDispatcher, opDispatcherSimClient], blockTime: 2, icon: OptimismIcon, + cache: cachePath, }, base: { id: 84532, @@ -33,5 +34,6 @@ export const CHAIN_CONFIGS: { dispatchers: [baseDispatcher, baseDispatcherSimClient], blockTime: 2, icon: BaseIcon, + cache: cachePath, }, }; diff --git a/app/utils/types/chain.ts b/app/utils/types/chain.ts index 80595cc..fc7e53e 100644 --- a/app/utils/types/chain.ts +++ b/app/utils/types/chain.ts @@ -5,4 +5,5 @@ export interface Chain { dispatchers: string[]; blockTime: number; icon: () => JSX.Element; + cache: string; }