-
Notifications
You must be signed in to change notification settings - Fork 77
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
Implement caching for parameters and identity storage contracts #2834
Conversation
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.
Looks good, but there are other ways how to reduce number of calls. Just to name a few:
- In the
ValidationService
we're separately checkingassertionSize
,assertionTriplesNumber
andassertionChunksNumber
. We're using 3 calls here. Instead, we can just use 1 callgetAssertion
, which would return all the data callScoreFunction
can be replaced with local implementation of the score function (same as we did for hashing) [Now as I see we don't use this function]- One more idea, maybe we can validate bid on publisher node before sending requests instead of validating on every node?
- Potentially we could also cache
getLog2PLDSFParams
, but we need to add events for that contract
There could be more optimizations, just ran through the code quickly
P.S. Looks like we're missing validateAssertion
for update receiver. Not related to the topic, but adding it here just not to forget later
@@ -406,10 +416,16 @@ class Web3Service { | |||
|
|||
async callContractFunction(contractInstance, functionName, args) { |
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.
Since we're using this function for identityId
, old logic for getIdentityId
function should be removed and we can add it to cached parameters since it's immutable
One more idea we should consider, what if we use MySQL as a key-value store instead of caching in memory? |
@@ -586,3 +588,16 @@ export const BLOCK_TIME_MILLIS = { | |||
}; | |||
|
|||
export const TRANSACTION_CONFIRMATIONS = 1; | |||
|
|||
export const CACHED_FUNCTIONS = { |
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.
Could you also please move the cached values from the scoring function ?
try { | ||
// eslint-disable-next-line no-await-in-loop | ||
result = await contractInstance[functionName](...args); | ||
if (CACHED_FUNCTIONS.ParametersStorage.includes(functionName)) { | ||
this.cacheParameter(functionName, result); | ||
} | ||
} catch (error) { |
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.
Is there a reason why we don't call "handleError" in the catch block anymore ? This was previously used to switch RPCs in case the error was due to RPC being down.
If this is intended, then the while loop is not necessary and can be removed.
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.
We switched to a new provider implementation in the ethers.js
that automatically hits different RPC after defined timeout, while
loop probably can be removed as we're not retrying the call anyway (because of throwing new error)
@@ -589,15 +589,19 @@ export const BLOCK_TIME_MILLIS = { | |||
|
|||
export const TRANSACTION_CONFIRMATIONS = 1; | |||
|
|||
export const CACHE_DATA_TYPES = { |
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.
Not sure I get why would we need this
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.
@@ -272,11 +273,28 @@ class Web3Service { | |||
} | |||
|
|||
cacheParameter(parameterName, parameterValue) { | |||
resultCache[parameterName] = parameterValue; | |||
console.log('PARAMETER IME', parameterName); | |||
const found = Object.values(CACHED_FUNCTIONS) |
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.
Why not just add contractName
as argument for the function?
} | ||
|
||
getCachedValue(parameterName) { | ||
return resultCache[parameterName]; | ||
if (CACHED_FUNCTIONS.ParametersStorage.some((item) => item.name === parameterName)) { |
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.
Why not just add contractName
as argument for the function?
src/constants/constants.js
Outdated
}; | ||
|
||
export const CACHED_FUNCTIONS = { | ||
ParametersStorage: [ |
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 it an object, with parameterName
as key and type
as value, then we don't need to iterate through all parameters every time.
If we remove types as I suggested in the comment above, we can just make it a Set
with constant O(1)
lookup
cacheParameter(contractName, parameterName, parameterValue) { | ||
const found = | ||
CACHED_FUNCTIONS[contractName] && | ||
CACHED_FUNCTIONS[contractName].find((item) => item.name === parameterName); |
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.
This is not needed if CACHED_FUNCTIONS
is an object/Set instead of array
@@ -589,15 +589,19 @@ export const BLOCK_TIME_MILLIS = { | |||
|
|||
export const TRANSACTION_CONFIRMATIONS = 1; | |||
|
|||
export const CACHE_DATA_TYPES = { |
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.
CACHED_FUNCTIONS[contractName].find((item) => item.name === parameterName); | ||
if (found) { | ||
const { type } = found; | ||
switch (type) { |
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.
Following the suggestion to remove types from constants, I would make it a separate function somewhere in the services
or even utils
for casting based on types of the event arguments in the ABI and cast it directly in the event handler instead of doing it here
getCachedValue(contractName, parameterName) { | ||
if ( | ||
CACHED_FUNCTIONS[contractName] && | ||
CACHED_FUNCTIONS[contractName].some((item) => item.name === parameterName) |
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.
This is not needed if CACHED_FUNCTIONS
is an object/Set instead of array
while (result === undefined) { | ||
result = this.getCachedValue(contractName, functionName); | ||
|
||
while (!result) { |
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.
while
loop here is redundant, we won't ever reiterate here
@@ -404,12 +432,15 @@ class Web3Service { | |||
} | |||
} | |||
|
|||
async callContractFunction(contractInstance, functionName, args) { | |||
async callContractFunction(contractInstance, functionName, args, contractName = null) { |
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.
Can't we add name
field to the contractInstance
during initialization?
Co-authored-by: Nikola Todorovic <nikolaztodorovic26@gmail.com>
Description
Added listener for Parameters storage contract. Implemented caching for functions inside parameters storage.
Type of change
How Has This Been Tested?
Tested in the local env, creating assets locally.
Checklist: