-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add simple cache on eth_call
#880
Conversation
Codecov ReportBase: 73.88% // Head: 74.16% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #880 +/- ##
==========================================
+ Coverage 73.88% 74.16% +0.28%
==========================================
Files 29 29
Lines 1815 1827 +12
Branches 336 339 +3
==========================================
+ Hits 1341 1355 +14
+ Misses 375 374 -1
+ Partials 99 98 -1
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
Some suggestions
packages/relay/src/lib/eth.ts
Outdated
@@ -1017,8 +1017,17 @@ export class EthImpl implements Eth { | |||
} | |||
} | |||
|
|||
let cachedResponse = this.cache.get(`eth_call: ${call.data} from ${call.to}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: add const for label. Maybe shorten key also
let cachedResponse = this.cache.get(`eth_call: ${call.data} from ${call.to}`); | |
const cacheKey = `eth_call:.${call.to}.${call.data}`; | |
let cachedResponse = this.cache.get(cacheKey); |
packages/relay/src/lib/eth.ts
Outdated
return EthImpl.prepend0x(Buffer.from(contractCallResponse.asBytes()).toString('hex')); | ||
const formattedCallReponse = EthImpl.prepend0x(Buffer.from(contractCallResponse.asBytes()).toString('hex')); | ||
|
||
this.cache.set(`eth_call: ${call.data} from ${call.to}`, formattedCallReponse, { ttl: 200 }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use cacheKey
here
packages/relay/src/lib/eth.ts
Outdated
@@ -1017,8 +1017,17 @@ export class EthImpl implements Eth { | |||
} | |||
} | |||
|
|||
let cachedResponse = this.cache.get(`eth_call: ${call.data} from ${call.to}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned the call.data
can get quite long.
In my exploration I went down the path of taking a hashing of the data to reduce it's length.
Maybe since the cache is so short lived it's not a biggie but let's make sure the key itself doesn't have length limits.
Maybe a simple approach of taking the first n characters also works if the hash approach is costly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanna avoid any potential error cases from a long data. maybe add a test case with a long data field if you stay with this approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make the ttl configureable
packages/relay/src/lib/eth.ts
Outdated
return EthImpl.prepend0x(Buffer.from(contractCallResponse.asBytes()).toString('hex')); | ||
const formattedCallReponse = EthImpl.prepend0x(Buffer.from(contractCallResponse.asBytes()).toString('hex')); | ||
|
||
this.cache.set(`eth_call: ${call.data} from ${call.to}`, formattedCallReponse, { ttl: 200 }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make the ttl value a config to allow for on demand tuning
Signed-off-by: georgi-l95 <glazarov95@gmail.com>
Signed-off-by: georgi-l95 <glazarov95@gmail.com>
Signed-off-by: georgi-l95 <glazarov95@gmail.com>
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
I think this cache could cause issues in the case where the result of a method from a contract depends not on its own state, but on the state of another contract. Such is the case with a Multicaller contract, where it only aggregates and returns results from multiple other contracts, but it doesn't update its own state. |
Hmm, I think you're right, but we have a ttl of 200ms, which is not so long, because those multicalls might take some time. Also this is a temporary solution and it's configurable if there is indeed problem with multicall queries. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
data = crypto.createHash('sha1').update(call.data).digest('hex'); // NOSONAR | ||
} | ||
|
||
const cacheKey = `eth_call:.${call.to}.${data}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens if data
is null/undefined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problems there we continue with the query as normal, I just didn’t want to calculate hash for a undefined, now that I think, I should’ve added a or call.data.length is bigger than 64(for example).
* Add simple cache on `eth_call` (#880) Adds a cache on eth_call request, based on `to` and `data` parameters for 200ms. Signed-off-by: georgi-l95 <glazarov95@gmail.com> * retrigger checks --------- Signed-off-by: georgi-l95 <glazarov95@gmail.com> Co-authored-by: Georgi Lazarov <glazarov95@gmail.com>
Signed-off-by: georgi-l95 glazarov95@gmail.com
Description:
Adds a cache on eth_call request, based on
to
anddata
parameters for 200ms.Related issue(s):
Fixes #877
Notes for reviewer:
Checklist