diff --git a/src/api.ts b/src/api.ts index 820c3677..e8b394e8 100755 --- a/src/api.ts +++ b/src/api.ts @@ -27,6 +27,7 @@ import { getSyncTime, removeFromNodeList, sanitizeIpAndPort, + removeOldestFilter, } from './utils' import crypto from 'crypto' import { logEventEmitter } from './logger' @@ -2799,6 +2800,9 @@ export const methods = { unsubscribe, type: Types.FilterTypes.block, } + if (filtersMap.size >= config.maxEntriesAllowed) { + removeOldestFilter(filtersMap) + } filtersMap.set(filterId.toString(), internalFilter) callback(null, filterId) @@ -2833,6 +2837,9 @@ export const methods = { unsubscribe, type: Types.FilterTypes.pendingTransaction, } + if (filtersMap.size >= config.maxEntriesAllowed) { + removeOldestFilter(filtersMap) + } filtersMap.set(filterId.toString(), internalFilter) callback(null, filterId) @@ -2934,6 +2941,9 @@ export const methods = { unsubscribe, type: Types.FilterTypes.log, } + if (filtersMap.size >= config.maxEntriesAllowed) { + removeOldestFilter(filtersMap) + } filtersMap.set(filterId.toString(), internalFilter) callback(null, filterId) diff --git a/src/config.ts b/src/config.ts index a633cf32..ae3e8be8 100644 --- a/src/config.ts +++ b/src/config.ts @@ -106,6 +106,7 @@ type Config = { } axiosTimeoutInMs: number enableBlacklistingIP: boolean + maxEntriesAllowed: number // maximum number of entries allowed for map to store } export type ServicePointTypes = 'aalg-warmup' @@ -249,4 +250,5 @@ export const CONFIG: Config = { }, axiosTimeoutInMs: 3000, enableBlacklistingIP: false, + maxEntriesAllowed: 10000, } diff --git a/src/utils.ts b/src/utils.ts index 38fda413..a60d10e0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -29,6 +29,7 @@ import { OriginalTxData, AccountTypesData, Account2, + InternalFilter } from './types' import Sntp from '@hapi/sntp' import { randomBytes, createHash } from 'crypto' @@ -1838,6 +1839,24 @@ export function sanitizeIpAndPort(ipPort: string): { isValid: boolean; error?: s return { isValid: true } } +export function removeOldestFilter(filtersMap: Map): void { + let oldestKey: string | undefined; + let oldestTimestamp = Infinity; + + // Iterate through the map to find the oldest entry + for (const [key, value] of filtersMap) { + if (value.filter.lastQueriedTimestamp < oldestTimestamp) { + oldestTimestamp = value.filter.lastQueriedTimestamp; + oldestKey = key; + } + } + + // Remove the oldest entry + if (oldestKey !== undefined) { + filtersMap.delete(oldestKey); + } +} + class Semaphore { private queue: (() => void)[] = [] private value: number