From f7780e0cd3b38ce7015ba42b9c4332642d023df3 Mon Sep 17 00:00:00 2001 From: nazariikyselevych Date: Wed, 29 Jan 2025 20:39:48 +0200 Subject: [PATCH] feat: add caching for token slots --- tests/tenderly-simulation-new.ts | 88 +++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 12 deletions(-) diff --git a/tests/tenderly-simulation-new.ts b/tests/tenderly-simulation-new.ts index 30e219cfd..05cdc2a23 100644 --- a/tests/tenderly-simulation-new.ts +++ b/tests/tenderly-simulation-new.ts @@ -120,11 +120,76 @@ interface SimulatedTransactionDetails { }; } +class TokenStorageSlotsCache { + private static TOKEN_STORAGE_SLOTS: Record< + number, + Record + > | null = null; + private static readonly TOKEN_STORAGE_SLOTS_FILEPATH = path.join( + __dirname, + 'token-storage-slots.json', + ); + + private static async loadTokenStorageSlots(): Promise< + Record> + > { + return JSON.parse( + await fs.readFile(TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS_FILEPATH, { + encoding: 'utf-8', + }), + ); + } + + private static async saveTokenStorageSlots(): Promise { + await fs.writeFile( + TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS_FILEPATH, + JSON.stringify(TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS, null, 2), + { encoding: 'utf-8' }, + ); + } + + static async getTokenStorageSlots( + chainId: number, + token: string, + ): Promise { + if (!TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS) { + TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS = + await TokenStorageSlotsCache.loadTokenStorageSlots(); + } + + return ( + TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS[chainId]?.[ + token.toLowerCase() + ] ?? null + ); + } + + static async setTokenStorageSlots( + chainId: number, + token: string, + slots: TokenStorageSlots, + ): Promise { + if (!TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS) { + TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS = + await TokenStorageSlotsCache.loadTokenStorageSlots(); + } + + TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS ||= {}; + TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS[chainId] ||= {}; + TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS[chainId][token.toLowerCase()] = + slots; + + void TokenStorageSlotsCache.saveTokenStorageSlots(); + } +} + export class TenderlySimulatorNew { + // public constants static readonly DEFAULT_OWNER = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; static readonly DEFAULT_SPENDER = '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; + // singleton private static instance: TenderlySimulatorNew; private constructor() {} @@ -522,14 +587,15 @@ export class TenderlySimulatorNew { throw new Error('Cannot provide storage slots for native token'); } - const jsonPath = path.join(__dirname, 'token-storage-slots.json'); - - const chainSlots = JSON.parse( - await fs.readFile(jsonPath, { encoding: 'utf-8' }), - ) as Record>; + // check cache + const cachedSlots = await TokenStorageSlotsCache.getTokenStorageSlots( + chainId, + normalizedToken, + ); - if (chainSlots[chainId]?.[normalizedToken]) { - return chainSlots[chainId][normalizedToken]; + // return if cached + if (cachedSlots) { + return cachedSlots; } // find the slots @@ -545,11 +611,9 @@ export class TenderlySimulatorNew { isVyper: balanceSlot.isVyper, }; - chainSlots[chainId] ||= {}; - chainSlots[chainId][normalizedToken] = slots; - const stringified = JSON.stringify(chainSlots, null, 2); - await fs.writeFile(jsonPath, stringified, { encoding: 'utf-8' }); + // no need to await + void TokenStorageSlotsCache.setTokenStorageSlots(chainId, token, slots); - return chainSlots[chainId][normalizedToken]; + return slots; } }