Skip to content

Commit 1209099

Browse files
authored
Cache eth_calls with in-memory cache (#410)
* Revert "Revert "Cache eth_calls in our InstrumentedEVMProvider (#406)" (#407)" This reverts commit 0dcd42e. * Cache RPC Responses with metrics * linter
1 parent 9e2851e commit 1209099

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

lib/handlers/evm/provider/InstrumentedEVMProvider.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,50 @@ export type InstrumentedEVMProviderProps = {
2525
export class InstrumentedEVMProvider extends ethers.providers.StaticJsonRpcProvider {
2626
private readonly name: ProviderName
2727
private readonly metricPrefix: string
28+
private readonly blockCache: Map<string, Promise<any>>
2829

2930
constructor({ url, network, name }: InstrumentedEVMProviderProps) {
3031
super(url, network)
3132
this.name = name
3233
this.metricPrefix = `RPC_${this.name}_${this.network.chainId}`
34+
this.blockCache = new Map()
35+
// Set an event listener to clear the cache on every new block.
36+
this.on('block', () => {
37+
metric.putMetric('RPCProviderCacheClear', 1, MetricLoggerUnit.Count)
38+
this.blockCache.clear()
39+
})
40+
}
41+
42+
// Adds caching functionality to the RPC provider
43+
override send(method: string, params: Array<any>): Promise<any> {
44+
// Only cache eth_call's.
45+
if (method !== 'eth_call') return super.send(method, params)
46+
let key: string | undefined = undefined
47+
48+
try {
49+
key = `call:${JSON.stringify(params)}`
50+
} catch (e) {
51+
metric.putMetric('RPCProviderCacheKeyError', 1, MetricLoggerUnit.Count)
52+
}
53+
54+
if (key) {
55+
const cached = this.blockCache.get(key)
56+
if (cached) {
57+
metric.putMetric('RPCProviderCacheHit', 1, MetricLoggerUnit.Count)
58+
return cached
59+
} else {
60+
metric.putMetric('RPCProviderCacheMiss', 1, MetricLoggerUnit.Count)
61+
}
62+
}
63+
64+
const result = super.send(method, params)
65+
66+
if (key) {
67+
metric.putMetric('RPCProviderCacheInsert', 1, MetricLoggerUnit.Count)
68+
this.blockCache.set(key, result)
69+
}
70+
71+
return result
3372
}
3473

3574
override call(transaction: Deferrable<TransactionRequest>, blockTag?: BlockTag | Promise<BlockTag>): Promise<string> {

0 commit comments

Comments
 (0)