Skip to content

[BUG] ChainStateCache.revalidate() resurrects evicted entries without re-applying the LRU bound, allowing the cache to grow past maxEntries #201

Description

@N-thnI

Priority: Medium

Description

ChainStateCache.getSwr()'s cache-miss path (chain-state-cache.ts:89-92) inserts into this.cache and then calls evictIfNeeded() to enforce maxEntries. The SWR background-refresh path, revalidate() (fired-and-forgotten from line 76), writes this.cache.set(key, {...}) on success at line 112 but never calls evictIfNeeded().

Failure scenario

With maxEntries set small and many distinct keys queried concurrently under load: key A is read as stale, triggers revalidate(A) in the background and is marked isRevalidating. Before A's fetch resolves, enough other keys are inserted to push A out via evictIfNeeded(). When A's revalidate() promise later resolves, it unconditionally re-adds A to cache, bypassing the bound entirely. Repeated across many stale/evicted keys under sustained load, the cache can grow past maxEntries again — reintroducing the unbounded-memory-growth risk that the recent LRU eviction fix (#171 / PR closing #185) was meant to close.

Suggested fix

Call evictIfNeeded() after the cache.set in revalidate()'s success path (line 112), same as the cache-miss path does.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third CampaignbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions