From a8c7806e63d09c39eb6c08ebfeaf9913fd865939 Mon Sep 17 00:00:00 2001 From: Milos Stanisavljevic Date: Mon, 11 Dec 2023 14:12:01 +0100 Subject: [PATCH 01/13] Implementation of caching and parameter storage handler --- src/constants/constants.js | 2 + .../blockchain/blockchain-module-manager.js | 8 +++ .../blockchain/implementation/web3-service.js | 71 +++++++++++++------ .../blockchain-event-listener-service.js | 19 +++++ 4 files changed, 79 insertions(+), 21 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index ea9f47e221..198965622a 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -554,6 +554,7 @@ export const CONTRACTS = { HUB_CONTRACT: 'HubContract', COMMIT_MANAGER_V1_U1_CONTRACT: 'CommitManagerV1U1Contract', SERVICE_AGREEMENT_V1_CONTRACT: 'ServiceAgreementV1Contract', + PARAMETERS_STORAGE_CONTRACT: 'ParametersStorageContract', }; export const CONTRACT_EVENTS = { @@ -563,6 +564,7 @@ export const CONTRACT_EVENTS = { PROFILE: ['AskUpdated'], COMMIT_MANAGER_V1: ['StateFinalized'], SERVICE_AGREEMENT_V1: ['ServiceAgreementV1Extended', 'ServiceAgreementV1Terminated'], + PARAMETERS_STORAGE: ['ParameterChanged'], }; export const NODE_ENVIRONMENTS = { diff --git a/src/modules/blockchain/blockchain-module-manager.js b/src/modules/blockchain/blockchain-module-manager.js index d7b8b98c19..1eddda3c16 100644 --- a/src/modules/blockchain/blockchain-module-manager.js +++ b/src/modules/blockchain/blockchain-module-manager.js @@ -26,6 +26,14 @@ class BlockchainModuleManager extends BaseModuleManager { ]); } + cacheParameter(blockchain, parameterName, parameterValue) { + console.log('CacheParametar module manager'); + return this.callImplementationFunction(blockchain, 'cacheParameter', [ + parameterName, + parameterValue, + ]); + } + getPrivateKey(blockchain) { return this.callImplementationFunction(blockchain, 'getPrivateKey'); } diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index dd0472aee6..e1bc8ef4b2 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -51,6 +51,17 @@ const ABIs = { const SCORING_FUNCTIONS = { 1: 'Log2PLDSF', }; +const cachedFunctionsList = [ + 'r0', + 'r1', + 'r2', + 'finalizationCommitsNumber', + 'updateCommitWindowDuration', + 'commitWindowDurationPerc', + 'proofWindowDurationPerc', + 'epochLength', +]; +const resultCache = {}; class Web3Service { async initialize(config, logger) { @@ -269,6 +280,11 @@ class Web3Service { } } + cacheParameter(parameterName, parameterValue) { + console.log('cache web3 service'); + resultCache[parameterName] = parameterValue; + } + initializeContract(contractName, contractAddress) { if (ABIs[contractName] != null) { this[`${contractName}Contract`] = new ethers.Contract( @@ -406,30 +422,42 @@ class Web3Service { async callContractFunction(contractInstance, functionName, args) { let result; - while (result === undefined) { - try { - // eslint-disable-next-line no-await-in-loop - result = await contractInstance[functionName](...args); - } catch (error) { - const decodedErrorData = this._decodeErrorData(error, contractInstance.interface); - - const functionFragment = contractInstance.interface.getFunction( - error.transaction.data.slice(0, 10), - ); - const inputs = functionFragment.inputs - .map((input, i) => { - const argName = input.name; - const argValue = this._formatArgument(args[i]); - return `${argName}=${argValue}`; - }) - .join(', '); + if (cachedFunctionsList.includes(functionName) && resultCache[functionName] !== undefined) { + console.log('cached!'); + result = resultCache[functionName]; + console.log(result); + } else { + while (result === undefined) { + try { + // eslint-disable-next-line no-await-in-loop + result = await contractInstance[functionName](...args); + if (cachedFunctionsList.includes(functionName)) { + resultCache[functionName] = result; + console.log(`Cached result for ${functionName}:`, result); + } + } catch (error) { + const decodedErrorData = this._decodeErrorData( + error, + contractInstance.interface, + ); - throw new Error( - `Call ${functionName}(${inputs}) failed, reason: ${decodedErrorData}`, - ); + const functionFragment = contractInstance.interface.getFunction( + error.transaction.data.slice(0, 10), + ); + const inputs = functionFragment.inputs + .map((input, i) => { + const argName = input.name; + const argValue = this._formatArgument(args[i]); + return `${argName}=${argValue}`; + }) + .join(', '); + + throw new Error( + `Call ${functionName}(${inputs}) failed, reason: ${decodedErrorData}`, + ); + } } } - return result; } @@ -904,6 +932,7 @@ class Web3Service { score: commit.score, })); } + // OVO OVDE TREBA DODATI MEMORY CACHE NAJPAMETNIJE URADITI U CALL CONTRACT FFFF async getR2() { const r2 = await this.callContractFunction(this.ParametersStorageContract, 'r2', []); diff --git a/src/service/blockchain-event-listener-service.js b/src/service/blockchain-event-listener-service.js index ea8f9611e4..5b4fb68b08 100644 --- a/src/service/blockchain-event-listener-service.js +++ b/src/service/blockchain-event-listener-service.js @@ -79,6 +79,12 @@ class BlockchainEventListenerService { currentBlock, CONTRACT_EVENTS.SERVICE_AGREEMENT_V1, ), + this.getContractEvents( + blockchainId, + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, + currentBlock, + CONTRACT_EVENTS.PARAMETERS_STORAGE, + ), ]; if (!devEnvironment) { @@ -227,6 +233,19 @@ class BlockchainEventListenerService { } } + async handleParameterChangedEvents(blockEvents) { + console.log('handler'); + for (const event of blockEvents) { + const { parameterName, parameterValue } = JSON.parse(event.data); + console.log('Handler', parameterName, parameterValue); + this.blockchainModuleManager.cacheParameter( + event.blockchainId, + parameterName, + parameterValue, + ); + } + } + handleNewContractEvents(blockEvents) { for (const event of blockEvents) { const { contractName, newContractAddress } = JSON.parse(event.data); From d0870dbeff7b9cb1d546e3416ffcf5199f7b615e Mon Sep 17 00:00:00 2001 From: Milos Stanisavljevic Date: Mon, 11 Dec 2023 15:02:38 +0100 Subject: [PATCH 02/13] caching code improvement and removing unnecessary logs --- src/constants/constants.js | 13 +++++++++++ .../blockchain/blockchain-module-manager.js | 1 - .../blockchain/implementation/web3-service.js | 23 +++++-------------- .../blockchain-event-listener-service.js | 2 -- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index 198965622a..d2791b5fdc 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -588,3 +588,16 @@ export const BLOCK_TIME_MILLIS = { }; export const TRANSACTION_CONFIRMATIONS = 1; + +export const CACHED_FUNCTIONS = { + ParametersStorage: [ + 'r0', + 'r1', + 'r2', + 'finalizationCommitsNumber', + 'updateCommitWindowDuration', + 'commitWindowDurationPerc', + 'proofWindowDurationPerc', + 'epochLength', + ], +}; diff --git a/src/modules/blockchain/blockchain-module-manager.js b/src/modules/blockchain/blockchain-module-manager.js index 1eddda3c16..4398c9f5b9 100644 --- a/src/modules/blockchain/blockchain-module-manager.js +++ b/src/modules/blockchain/blockchain-module-manager.js @@ -27,7 +27,6 @@ class BlockchainModuleManager extends BaseModuleManager { } cacheParameter(blockchain, parameterName, parameterValue) { - console.log('CacheParametar module manager'); return this.callImplementationFunction(blockchain, 'cacheParameter', [ parameterName, parameterValue, diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index e1bc8ef4b2..747daa1b75 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -19,6 +19,7 @@ import { HTTP_RPC_PROVIDER_PRIORITY, FALLBACK_PROVIDER_QUORUM, RPC_PROVIDER_STALL_TIMEOUT, + CACHED_FUNCTIONS, } from '../../../constants/constants.js'; const require = createRequire(import.meta.url); @@ -51,16 +52,6 @@ const ABIs = { const SCORING_FUNCTIONS = { 1: 'Log2PLDSF', }; -const cachedFunctionsList = [ - 'r0', - 'r1', - 'r2', - 'finalizationCommitsNumber', - 'updateCommitWindowDuration', - 'commitWindowDurationPerc', - 'proofWindowDurationPerc', - 'epochLength', -]; const resultCache = {}; class Web3Service { @@ -281,7 +272,6 @@ class Web3Service { } cacheParameter(parameterName, parameterValue) { - console.log('cache web3 service'); resultCache[parameterName] = parameterValue; } @@ -422,18 +412,18 @@ class Web3Service { async callContractFunction(contractInstance, functionName, args) { let result; - if (cachedFunctionsList.includes(functionName) && resultCache[functionName] !== undefined) { - console.log('cached!'); + if ( + CACHED_FUNCTIONS.ParametersStorage.includes(functionName) && + resultCache[functionName] !== undefined + ) { result = resultCache[functionName]; - console.log(result); } else { while (result === undefined) { try { // eslint-disable-next-line no-await-in-loop result = await contractInstance[functionName](...args); - if (cachedFunctionsList.includes(functionName)) { + if (CACHED_FUNCTIONS.ParametersStorage.includes(functionName)) { resultCache[functionName] = result; - console.log(`Cached result for ${functionName}:`, result); } } catch (error) { const decodedErrorData = this._decodeErrorData( @@ -932,7 +922,6 @@ class Web3Service { score: commit.score, })); } - // OVO OVDE TREBA DODATI MEMORY CACHE NAJPAMETNIJE URADITI U CALL CONTRACT FFFF async getR2() { const r2 = await this.callContractFunction(this.ParametersStorageContract, 'r2', []); diff --git a/src/service/blockchain-event-listener-service.js b/src/service/blockchain-event-listener-service.js index 5b4fb68b08..1f7e65911b 100644 --- a/src/service/blockchain-event-listener-service.js +++ b/src/service/blockchain-event-listener-service.js @@ -234,10 +234,8 @@ class BlockchainEventListenerService { } async handleParameterChangedEvents(blockEvents) { - console.log('handler'); for (const event of blockEvents) { const { parameterName, parameterValue } = JSON.parse(event.data); - console.log('Handler', parameterName, parameterValue); this.blockchainModuleManager.cacheParameter( event.blockchainId, parameterName, From ade10907f8c13120decd0307d169442122618b8d Mon Sep 17 00:00:00 2001 From: Milos Stanisavljevic Date: Mon, 11 Dec 2023 15:39:48 +0100 Subject: [PATCH 03/13] code improvement --- src/modules/blockchain/implementation/web3-service.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 747daa1b75..5bcd4edd05 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -275,6 +275,10 @@ class Web3Service { resultCache[parameterName] = parameterValue; } + getCachedValue(parameterName) { + return resultCache[parameterName]; + } + initializeContract(contractName, contractAddress) { if (ABIs[contractName] != null) { this[`${contractName}Contract`] = new ethers.Contract( @@ -412,11 +416,8 @@ class Web3Service { async callContractFunction(contractInstance, functionName, args) { let result; - if ( - CACHED_FUNCTIONS.ParametersStorage.includes(functionName) && - resultCache[functionName] !== undefined - ) { - result = resultCache[functionName]; + if (CACHED_FUNCTIONS.ParametersStorage.includes(functionName)) { + result = this.getCachedValue(functionName); } else { while (result === undefined) { try { From 317684504b015f29fe04a474c98b650f44920a8d Mon Sep 17 00:00:00 2001 From: Milos Stanisavljevic Date: Mon, 11 Dec 2023 16:00:19 +0100 Subject: [PATCH 04/13] undefined bugfix --- .../blockchain/implementation/web3-service.js | 53 +++++++++---------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 5bcd4edd05..58adbd9b9d 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -418,37 +418,34 @@ class Web3Service { let result; if (CACHED_FUNCTIONS.ParametersStorage.includes(functionName)) { result = this.getCachedValue(functionName); - } else { - while (result === undefined) { - try { - // eslint-disable-next-line no-await-in-loop - result = await contractInstance[functionName](...args); - if (CACHED_FUNCTIONS.ParametersStorage.includes(functionName)) { - resultCache[functionName] = result; - } - } catch (error) { - const decodedErrorData = this._decodeErrorData( - error, - contractInstance.interface, - ); - - const functionFragment = contractInstance.interface.getFunction( - error.transaction.data.slice(0, 10), - ); - const inputs = functionFragment.inputs - .map((input, i) => { - const argName = input.name; - const argValue = this._formatArgument(args[i]); - return `${argName}=${argValue}`; - }) - .join(', '); - - throw new Error( - `Call ${functionName}(${inputs}) failed, reason: ${decodedErrorData}`, - ); + } + while (!result) { + 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) { + const decodedErrorData = this._decodeErrorData(error, contractInstance.interface); + + const functionFragment = contractInstance.interface.getFunction( + error.transaction.data.slice(0, 10), + ); + const inputs = functionFragment.inputs + .map((input, i) => { + const argName = input.name; + const argValue = this._formatArgument(args[i]); + return `${argName}=${argValue}`; + }) + .join(', '); + + throw new Error( + `Call ${functionName}(${inputs}) failed, reason: ${decodedErrorData}`, + ); } } + return result; } From 829599f9fc74352f783a85ccc12d4158762e6855 Mon Sep 17 00:00:00 2001 From: Milos Stanisavljevic Date: Wed, 13 Dec 2023 12:27:31 +0100 Subject: [PATCH 05/13] updated cache to be scalable --- src/constants/constants.js | 20 +++++++----- .../blockchain/implementation/web3-service.js | 31 ++++++++++++++----- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index d2791b5fdc..95882baaac 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -589,15 +589,19 @@ export const BLOCK_TIME_MILLIS = { export const TRANSACTION_CONFIRMATIONS = 1; +export const CACHE_DATA_TYPES = { + NUMBER: 'number', +}; + export const CACHED_FUNCTIONS = { ParametersStorage: [ - 'r0', - 'r1', - 'r2', - 'finalizationCommitsNumber', - 'updateCommitWindowDuration', - 'commitWindowDurationPerc', - 'proofWindowDurationPerc', - 'epochLength', + { name: 'r0', type: CACHE_DATA_TYPES.NUMBER }, + { name: 'r1', type: CACHE_DATA_TYPES.NUMBER }, + { name: 'r2', type: CACHE_DATA_TYPES.NUMBER }, + { name: 'finalizationCommitsNumber', type: CACHE_DATA_TYPES.NUMBER }, + { name: 'updateCommitWindowDuration', type: CACHE_DATA_TYPES.NUMBER }, + { name: 'commitWindowDurationPerc', type: CACHE_DATA_TYPES.NUMBER }, + { name: 'proofWindowDurationPerc', type: CACHE_DATA_TYPES.NUMBER }, + { name: 'epochLength', type: CACHE_DATA_TYPES.NUMBER }, ], }; diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 58adbd9b9d..ed442d068e 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -20,6 +20,7 @@ import { FALLBACK_PROVIDER_QUORUM, RPC_PROVIDER_STALL_TIMEOUT, CACHED_FUNCTIONS, + CACHE_DATA_TYPES, } from '../../../constants/constants.js'; const require = createRequire(import.meta.url); @@ -272,11 +273,28 @@ class Web3Service { } cacheParameter(parameterName, parameterValue) { - resultCache[parameterName] = parameterValue; + console.log('PARAMETER IME', parameterName); + const found = Object.values(CACHED_FUNCTIONS) + .flat() + .find((item) => item.name === parameterName); + if (found) { + console.log('NADJENO?', found); + const { type } = found; + + switch (type) { + case CACHE_DATA_TYPES.NUMBER: + resultCache[parameterName] = Number(parameterValue); + break; + default: + resultCache[parameterName] = parameterValue; + } + } } getCachedValue(parameterName) { - return resultCache[parameterName]; + if (CACHED_FUNCTIONS.ParametersStorage.some((item) => item.name === parameterName)) { + return resultCache[parameterName]; + } } initializeContract(contractName, contractAddress) { @@ -416,16 +434,13 @@ class Web3Service { async callContractFunction(contractInstance, functionName, args) { let result; - if (CACHED_FUNCTIONS.ParametersStorage.includes(functionName)) { - result = this.getCachedValue(functionName); - } + result = this.getCachedValue(functionName); + while (!result) { try { // eslint-disable-next-line no-await-in-loop result = await contractInstance[functionName](...args); - if (CACHED_FUNCTIONS.ParametersStorage.includes(functionName)) { - this.cacheParameter(functionName, result); - } + this.cacheParameter(functionName, result); } catch (error) { const decodedErrorData = this._decodeErrorData(error, contractInstance.interface); From 4ac849d34573d840d6dd6ceb22b282bbc76b5623 Mon Sep 17 00:00:00 2001 From: Milos Stanisavljevic Date: Wed, 13 Dec 2023 12:28:14 +0100 Subject: [PATCH 06/13] updated cache to be scalable --- src/modules/blockchain/implementation/web3-service.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index ed442d068e..7f74401d31 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -273,12 +273,10 @@ class Web3Service { } cacheParameter(parameterName, parameterValue) { - console.log('PARAMETER IME', parameterName); const found = Object.values(CACHED_FUNCTIONS) .flat() .find((item) => item.name === parameterName); if (found) { - console.log('NADJENO?', found); const { type } = found; switch (type) { From d44ed6dad8d0020ef4ec8e213401165cde532b68 Mon Sep 17 00:00:00 2001 From: Milos Stanisavljevic Date: Thu, 14 Dec 2023 14:08:34 +0100 Subject: [PATCH 07/13] added contractName as parameter in caching --- .../blockchain/implementation/web3-service.js | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 7f74401d31..703ae3a68e 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -272,13 +272,12 @@ class Web3Service { } } - cacheParameter(parameterName, parameterValue) { - const found = Object.values(CACHED_FUNCTIONS) - .flat() - .find((item) => item.name === parameterName); + cacheParameter(contractName, parameterName, parameterValue) { + const found = + CACHED_FUNCTIONS[contractName] && + CACHED_FUNCTIONS[contractName].find((item) => item.name === parameterName); if (found) { const { type } = found; - switch (type) { case CACHE_DATA_TYPES.NUMBER: resultCache[parameterName] = Number(parameterValue); @@ -289,8 +288,11 @@ class Web3Service { } } - getCachedValue(parameterName) { - if (CACHED_FUNCTIONS.ParametersStorage.some((item) => item.name === parameterName)) { + getCachedValue(contractName, parameterName) { + if ( + CACHED_FUNCTIONS[contractName] && + CACHED_FUNCTIONS[contractName].some((item) => item.name === parameterName) + ) { return resultCache[parameterName]; } } @@ -430,15 +432,15 @@ class Web3Service { } } - async callContractFunction(contractInstance, functionName, args) { + async callContractFunction(contractInstance, functionName, args, contractName = null) { let result; - result = this.getCachedValue(functionName); + result = this.getCachedValue(contractName, functionName); while (!result) { try { // eslint-disable-next-line no-await-in-loop result = await contractInstance[functionName](...args); - this.cacheParameter(functionName, result); + this.cacheParameter(contractName, functionName, result); } catch (error) { const decodedErrorData = this._decodeErrorData(error, contractInstance.interface); @@ -935,17 +937,32 @@ class Web3Service { } async getR2() { - const r2 = await this.callContractFunction(this.ParametersStorageContract, 'r2', []); + const r2 = await this.callContractFunction( + this.ParametersStorageContract, + 'r2', + [], + 'ParametersStorage', + ); return r2; } async getR1() { - const r1 = await this.callContractFunction(this.ParametersStorageContract, 'r1', []); + const r1 = await this.callContractFunction( + this.ParametersStorageContract, + 'r1', + [], + 'ParametersStorage', + ); return r1; } async getR0() { - const r0 = await this.callContractFunction(this.ParametersStorageContract, 'r0', []); + const r0 = await this.callContractFunction( + this.ParametersStorageContract, + 'r0', + [], + 'ParametersStorage', + ); return r0; } @@ -954,6 +971,7 @@ class Web3Service { this.ParametersStorageContract, 'finalizationCommitsNumber', [], + 'ParametersStorage', ); return finalizationCommitsNumber; } @@ -1125,6 +1143,7 @@ class Web3Service { this.ParametersStorageContract, 'updateCommitWindowDuration', [], + 'ParametersStorage', ); return Number(commitWindowDurationPerc); } @@ -1134,6 +1153,7 @@ class Web3Service { this.ParametersStorageContract, 'commitWindowDurationPerc', [], + 'ParametersStorage', ); return Number(commitWindowDurationPerc); } @@ -1143,6 +1163,7 @@ class Web3Service { this.ParametersStorageContract, 'proofWindowDurationPerc', [], + 'ParametersStorage', ); } @@ -1151,6 +1172,7 @@ class Web3Service { this.ParametersStorageContract, 'epochLength', [], + 'ParametersStorage', ); return Number(epochLength); } From 844ddf03cfd85df1adebd39f189c8250a2ee8127 Mon Sep 17 00:00:00 2001 From: Uladzislau Hubar Date: Thu, 14 Dec 2023 17:13:26 +0100 Subject: [PATCH 08/13] Reworked contract calls caching, adding caching for Log2PLDSF function and parameter values casting based on ABIs --- src/constants/constants.js | 29 +++--- .../blockchain/blockchain-module-manager.js | 16 ++- .../blockchain/implementation/web3-service.js | 99 ++++++++++--------- .../blockchain-event-listener-service.js | 44 ++++++++- src/service/service-agreement-service.js | 9 +- 5 files changed, 121 insertions(+), 76 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index 95882baaac..00ed18b2e7 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -555,6 +555,7 @@ export const CONTRACTS = { COMMIT_MANAGER_V1_U1_CONTRACT: 'CommitManagerV1U1Contract', SERVICE_AGREEMENT_V1_CONTRACT: 'ServiceAgreementV1Contract', PARAMETERS_STORAGE_CONTRACT: 'ParametersStorageContract', + LOG2PLDSF: 'Log2PLDSFContract', }; export const CONTRACT_EVENTS = { @@ -565,6 +566,7 @@ export const CONTRACT_EVENTS = { COMMIT_MANAGER_V1: ['StateFinalized'], SERVICE_AGREEMENT_V1: ['ServiceAgreementV1Extended', 'ServiceAgreementV1Terminated'], PARAMETERS_STORAGE: ['ParameterChanged'], + LOG2PLDSF: ['ParameterChanged'], }; export const NODE_ENVIRONMENTS = { @@ -589,19 +591,20 @@ export const BLOCK_TIME_MILLIS = { export const TRANSACTION_CONFIRMATIONS = 1; -export const CACHE_DATA_TYPES = { - NUMBER: 'number', +export const SOLIDITY_TYPES_MAP = { + uint256: Number, }; -export const CACHED_FUNCTIONS = { - ParametersStorage: [ - { name: 'r0', type: CACHE_DATA_TYPES.NUMBER }, - { name: 'r1', type: CACHE_DATA_TYPES.NUMBER }, - { name: 'r2', type: CACHE_DATA_TYPES.NUMBER }, - { name: 'finalizationCommitsNumber', type: CACHE_DATA_TYPES.NUMBER }, - { name: 'updateCommitWindowDuration', type: CACHE_DATA_TYPES.NUMBER }, - { name: 'commitWindowDurationPerc', type: CACHE_DATA_TYPES.NUMBER }, - { name: 'proofWindowDurationPerc', type: CACHE_DATA_TYPES.NUMBER }, - { name: 'epochLength', type: CACHE_DATA_TYPES.NUMBER }, - ], +export const CACHED_CONTRACT_CALLS = { + ParametersStorageContract: new Set([ + 'r0', + 'r1', + 'r2', + 'finalizationCommitsNumber', + 'updateCommitWindowDuration', + 'commitWindowDurationPerc', + 'proofWindowDurationPerc', + 'epochLength', + ]), + Log2PLDSFContract: new Set(['getParameters']), }; diff --git a/src/modules/blockchain/blockchain-module-manager.js b/src/modules/blockchain/blockchain-module-manager.js index 4398c9f5b9..f9ed54f02f 100644 --- a/src/modules/blockchain/blockchain-module-manager.js +++ b/src/modules/blockchain/blockchain-module-manager.js @@ -26,13 +26,21 @@ class BlockchainModuleManager extends BaseModuleManager { ]); } - cacheParameter(blockchain, parameterName, parameterValue) { - return this.callImplementationFunction(blockchain, 'cacheParameter', [ + setContractCallCache(blockchain, contractName, parameterName, parameterValue) { + return this.callImplementationFunction(blockchain, 'setContractCallCache', [ + contractName, parameterName, parameterValue, ]); } + resetContractCallCache(blockchain, contract, parameterName) { + return this.callImplementationFunction(blockchain, 'resetContractCallCache', [ + contract, + parameterName, + ]); + } + getPrivateKey(blockchain) { return this.callImplementationFunction(blockchain, 'getPrivateKey'); } @@ -423,6 +431,10 @@ class BlockchainModuleManager extends BaseModuleManager { async hasPendingUpdate(blockchain, tokenId) { return this.callImplementationFunction(blockchain, 'hasPendingUpdate', [tokenId]); } + + getABI(blockchain, contractName) { + return this.callImplementationFunction(blockchain, 'getABI', [contractName]); + } } export default BlockchainModuleManager; diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 703ae3a68e..a05c8b0b5c 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -19,8 +19,7 @@ import { HTTP_RPC_PROVIDER_PRIORITY, FALLBACK_PROVIDER_QUORUM, RPC_PROVIDER_STALL_TIMEOUT, - CACHED_FUNCTIONS, - CACHE_DATA_TYPES, + CACHED_CONTRACT_CALLS, } from '../../../constants/constants.js'; const require = createRequire(import.meta.url); @@ -53,7 +52,7 @@ const ABIs = { const SCORING_FUNCTIONS = { 1: 'Log2PLDSF', }; -const resultCache = {}; +const contractCallCache = {}; class Web3Service { async initialize(config, logger) { @@ -272,28 +271,27 @@ class Web3Service { } } - cacheParameter(contractName, parameterName, parameterValue) { - const found = - CACHED_FUNCTIONS[contractName] && - CACHED_FUNCTIONS[contractName].find((item) => item.name === parameterName); - if (found) { - const { type } = found; - switch (type) { - case CACHE_DATA_TYPES.NUMBER: - resultCache[parameterName] = Number(parameterValue); - break; - default: - resultCache[parameterName] = parameterValue; + setContractCallCache(contractName, parameterName, parameterValue) { + if (CACHED_CONTRACT_CALLS[contractName]?.has(parameterName)) { + if (!contractCallCache[contractName]) { + contractCallCache[contractName] = {}; } + contractCallCache[contractName][parameterName] = parameterValue; } } - getCachedValue(contractName, parameterName) { + resetContractCallCache(contract, parameterName) { + if (contractCallCache[contract]) { + contractCallCache[contract][parameterName] = null; + } + } + + getContractCallCache(contractName, parameterName) { if ( - CACHED_FUNCTIONS[contractName] && - CACHED_FUNCTIONS[contractName].some((item) => item.name === parameterName) + CACHED_CONTRACT_CALLS[contractName]?.has(parameterName) && + contractCallCache[contractName] ) { - return resultCache[parameterName]; + return contractCallCache[contractName][parameterName]; } } @@ -433,32 +431,30 @@ class Web3Service { } async callContractFunction(contractInstance, functionName, args, contractName = null) { - let result; - result = this.getCachedValue(contractName, functionName); + let result = this.getContractCallCache(contractName, functionName); - while (!result) { - try { - // eslint-disable-next-line no-await-in-loop + try { + if (!result) { result = await contractInstance[functionName](...args); - this.cacheParameter(contractName, functionName, result); - } catch (error) { - const decodedErrorData = this._decodeErrorData(error, contractInstance.interface); + if (contractName) { + this.setContractCallCache(contractName, functionName, result); + } + } + } catch (error) { + const decodedErrorData = this._decodeErrorData(error, contractInstance.interface); - const functionFragment = contractInstance.interface.getFunction( - error.transaction.data.slice(0, 10), - ); - const inputs = functionFragment.inputs - .map((input, i) => { - const argName = input.name; - const argValue = this._formatArgument(args[i]); - return `${argName}=${argValue}`; - }) - .join(', '); + const functionFragment = contractInstance.interface.getFunction( + error.transaction.data.slice(0, 10), + ); + const inputs = functionFragment.inputs + .map((input, i) => { + const argName = input.name; + const argValue = this._formatArgument(args[i]); + return `${argName}=${argValue}`; + }) + .join(', '); - throw new Error( - `Call ${functionName}(${inputs}) failed, reason: ${decodedErrorData}`, - ); - } + throw new Error(`Call ${functionName}(${inputs}) failed, reason: ${decodedErrorData}`); } return result; @@ -941,7 +937,7 @@ class Web3Service { this.ParametersStorageContract, 'r2', [], - 'ParametersStorage', + 'ParametersStorageContract', ); return r2; } @@ -951,7 +947,7 @@ class Web3Service { this.ParametersStorageContract, 'r1', [], - 'ParametersStorage', + 'ParametersStorageContract', ); return r1; } @@ -961,7 +957,7 @@ class Web3Service { this.ParametersStorageContract, 'r0', [], - 'ParametersStorage', + 'ParametersStorageContract', ); return r0; } @@ -971,7 +967,7 @@ class Web3Service { this.ParametersStorageContract, 'finalizationCommitsNumber', [], - 'ParametersStorage', + 'ParametersStorageContract', ); return finalizationCommitsNumber; } @@ -1143,7 +1139,7 @@ class Web3Service { this.ParametersStorageContract, 'updateCommitWindowDuration', [], - 'ParametersStorage', + 'ParametersStorageContract', ); return Number(commitWindowDurationPerc); } @@ -1153,7 +1149,7 @@ class Web3Service { this.ParametersStorageContract, 'commitWindowDurationPerc', [], - 'ParametersStorage', + 'ParametersStorageContract', ); return Number(commitWindowDurationPerc); } @@ -1163,7 +1159,7 @@ class Web3Service { this.ParametersStorageContract, 'proofWindowDurationPerc', [], - 'ParametersStorage', + 'ParametersStorageContract', ); } @@ -1172,7 +1168,7 @@ class Web3Service { this.ParametersStorageContract, 'epochLength', [], - 'ParametersStorage', + 'ParametersStorageContract', ); return Number(epochLength); } @@ -1204,6 +1200,7 @@ class Web3Service { this.scoringFunctionsContracts[1], 'getParameters', [], + 'Log2PLDSFContract', ); const params = {}; @@ -1242,6 +1239,10 @@ class Web3Service { tokenId, ]); } + + getABI(contractName) { + return this[contractName].interface; + } } export default Web3Service; diff --git a/src/service/blockchain-event-listener-service.js b/src/service/blockchain-event-listener-service.js index 1f7e65911b..a19a6bf6ff 100644 --- a/src/service/blockchain-event-listener-service.js +++ b/src/service/blockchain-event-listener-service.js @@ -6,6 +6,7 @@ import { NODE_ENVIRONMENTS, PENDING_STORAGE_REPOSITORIES, CONTRACT_EVENTS, + SOLIDITY_TYPES_MAP, } from '../constants/constants.js'; const MAXIMUM_FETCH_EVENTS_FAILED_COUNT = 5; @@ -85,6 +86,12 @@ class BlockchainEventListenerService { currentBlock, CONTRACT_EVENTS.PARAMETERS_STORAGE, ), + this.getContractEvents( + blockchainId, + CONTRACTS.LOG2PLDSF, + currentBlock, + CONTRACT_EVENTS.LOG2PLDSF, + ), ]; if (!devEnvironment) { @@ -235,12 +242,39 @@ class BlockchainEventListenerService { async handleParameterChangedEvents(blockEvents) { for (const event of blockEvents) { + const { blockchainId, contract, event: eventName } = event; const { parameterName, parameterValue } = JSON.parse(event.data); - this.blockchainModuleManager.cacheParameter( - event.blockchainId, - parameterName, - parameterValue, - ); + + if (contract === CONTRACTS.LOG2PLDSF) { + this.blockchainModuleManager.resetContractCallCache( + blockchainId, + contract, + 'getParameters', + ); + } else { + const contractABI = this.blockchainModuleManager.getABI(blockchainId, contract); + + const eventNameWithArgs = Object.keys(contractABI.events).find((contractEvent) => + contractEvent.startsWith(eventName), + ); + + const parameterValueSolidityType = contractABI.events[ + eventNameWithArgs + ].inputs.find((input) => input.name === 'parameterValue').type; + + const castedParameterValue = Object.keys(SOLIDITY_TYPES_MAP).includes( + parameterValueSolidityType, + ) + ? SOLIDITY_TYPES_MAP[parameterValueSolidityType](parameterValue) + : parameterValue; + + this.blockchainModuleManager.setContractCallCache( + blockchainId, + contract, + parameterName, + castedParameterValue, + ); + } } } diff --git a/src/service/service-agreement-service.js b/src/service/service-agreement-service.js index d1f0f17ca1..dd38fc88e3 100644 --- a/src/service/service-agreement-service.js +++ b/src/service/service-agreement-service.js @@ -39,12 +39,7 @@ class ServiceAgreementService { keyHash, ); - // todo: store this in a more appropriate way - if (!this.log2PLDSFParams) { - this.log2PLDSFParams = await this.blockchainModuleManager.getLog2PLDSFParams( - blockchainId, - ); - } + const log2PLDSFParams = await this.blockchainModuleManager.getLog2PLDSFParams(blockchainId); const { distanceMappingCoefficient, @@ -57,7 +52,7 @@ class ServiceAgreementService { c, distanceExponent, d, - } = this.log2PLDSFParams; + } = log2PLDSFParams; const distanceUint256BN = this.blockchainModuleManager.toBigNumber( blockchainId, From 254fc6315f958a7a3ad300dbe18ea9085182e5a3 Mon Sep 17 00:00:00 2001 From: Uladzislau Hubar Date: Fri, 15 Dec 2023 01:35:17 +0100 Subject: [PATCH 09/13] Moved some complexity from BlockchainEventListener to Web3Service --- .../blockchain/blockchain-module-manager.js | 18 ++++++++++--- .../blockchain/implementation/web3-service.js | 15 ++++++++--- .../blockchain-event-listener-service.js | 25 ++++++++----------- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/modules/blockchain/blockchain-module-manager.js b/src/modules/blockchain/blockchain-module-manager.js index f9ed54f02f..f2061b9430 100644 --- a/src/modules/blockchain/blockchain-module-manager.js +++ b/src/modules/blockchain/blockchain-module-manager.js @@ -41,6 +41,20 @@ class BlockchainModuleManager extends BaseModuleManager { ]); } + getContractEventABI(blockchain, contractName, eventName) { + return this.callImplementationFunction(blockchain, 'getContractEventABI', [ + contractName, + eventName, + ]); + } + + fromSolidityType(blockchain, solidityType, parameterValue) { + return this.callImplementationFunction(blockchain, 'fromSolidityType', [ + solidityType, + parameterValue, + ]); + } + getPrivateKey(blockchain) { return this.callImplementationFunction(blockchain, 'getPrivateKey'); } @@ -431,10 +445,6 @@ class BlockchainModuleManager extends BaseModuleManager { async hasPendingUpdate(blockchain, tokenId) { return this.callImplementationFunction(blockchain, 'hasPendingUpdate', [tokenId]); } - - getABI(blockchain, contractName) { - return this.callImplementationFunction(blockchain, 'getABI', [contractName]); - } } export default BlockchainModuleManager; diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index a05c8b0b5c..34388a071c 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -8,6 +8,7 @@ import { SOLIDITY_ERROR_STRING_PREFIX, SOLIDITY_PANIC_CODE_PREFIX, SOLIDITY_PANIC_REASONS, + SOLIDITY_TYPES_MAP, ZERO_PREFIX, DEFAULT_BLOCKCHAIN_EVENT_SYNC_PERIOD_IN_MILLS, MAXIMUM_NUMBERS_OF_BLOCKS_TO_FETCH, @@ -295,6 +296,16 @@ class Web3Service { } } + getContractEventABI(contractName, eventName) { + return this[contractName].interface.getEvent(eventName); + } + + fromSolidityType(solidityType, parameterValue) { + return SOLIDITY_TYPES_MAP[solidityType] + ? SOLIDITY_TYPES_MAP[solidityType](parameterValue) + : parameterValue; + } + initializeContract(contractName, contractAddress) { if (ABIs[contractName] != null) { this[`${contractName}Contract`] = new ethers.Contract( @@ -1239,10 +1250,6 @@ class Web3Service { tokenId, ]); } - - getABI(contractName) { - return this[contractName].interface; - } } export default Web3Service; diff --git a/src/service/blockchain-event-listener-service.js b/src/service/blockchain-event-listener-service.js index a19a6bf6ff..d19bd59393 100644 --- a/src/service/blockchain-event-listener-service.js +++ b/src/service/blockchain-event-listener-service.js @@ -6,7 +6,6 @@ import { NODE_ENVIRONMENTS, PENDING_STORAGE_REPOSITORIES, CONTRACT_EVENTS, - SOLIDITY_TYPES_MAP, } from '../constants/constants.js'; const MAXIMUM_FETCH_EVENTS_FAILED_COUNT = 5; @@ -252,21 +251,19 @@ class BlockchainEventListenerService { 'getParameters', ); } else { - const contractABI = this.blockchainModuleManager.getABI(blockchainId, contract); - - const eventNameWithArgs = Object.keys(contractABI.events).find((contractEvent) => - contractEvent.startsWith(eventName), + const eventABI = this.blockchainModuleManager.getContractEventABI( + blockchainId, + contract, + eventName, ); + const parameterSolidityType = eventABI.inputs.find( + (input) => input.name === 'parameterValue', + ).type; - const parameterValueSolidityType = contractABI.events[ - eventNameWithArgs - ].inputs.find((input) => input.name === 'parameterValue').type; - - const castedParameterValue = Object.keys(SOLIDITY_TYPES_MAP).includes( - parameterValueSolidityType, - ) - ? SOLIDITY_TYPES_MAP[parameterValueSolidityType](parameterValue) - : parameterValue; + const castedParameterValue = this.blockchainModuleManager.fromSolidityType( + parameterSolidityType, + parameterValue, + ); this.blockchainModuleManager.setContractCallCache( blockchainId, From 70488b318bea550f576d5ecc15ca5e93ead81f51 Mon Sep 17 00:00:00 2001 From: Uladzislau Hubar Date: Fri, 15 Dec 2023 02:18:35 +0100 Subject: [PATCH 10/13] Removed unused function from web3-service, moved solidity types casting directly to the callContractFunction --- src/constants/constants.js | 13 +- .../blockchain/blockchain-module-manager.js | 23 ---- .../blockchain/implementation/web3-service.js | 130 ++++++------------ 3 files changed, 54 insertions(+), 112 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index 00ed18b2e7..3158469986 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -592,7 +592,18 @@ export const BLOCK_TIME_MILLIS = { export const TRANSACTION_CONFIRMATIONS = 1; export const SOLIDITY_TYPES_MAP = { - uint256: Number, + uint8: (value) => Number(value), + uint16: (value) => Number(value), + uint32: (value) => Number(value), + uint72: (value) => Number(value), + uint96: (value) => Number(value), + uint128: (value) => Number(value), + uint256: (value) => Number(value), + + 'uint8[]': (values) => values.map((value) => Number(value)), + 'uint32[]': (values) => values.map((value) => Number(value)), + 'uint96[]': (values) => values.map((value) => Number(value)), + 'uint256[]': (values) => values.map((value) => Number(value)), }; export const CACHED_CONTRACT_CALLS = { diff --git a/src/modules/blockchain/blockchain-module-manager.js b/src/modules/blockchain/blockchain-module-manager.js index f2061b9430..fbbc1302bf 100644 --- a/src/modules/blockchain/blockchain-module-manager.js +++ b/src/modules/blockchain/blockchain-module-manager.js @@ -67,20 +67,12 @@ class BlockchainModuleManager extends BaseModuleManager { return this.callImplementationFunction(blockchain, 'getManagementKey'); } - async isHubContract(blockchain, contractAddress) { - return this.callImplementationFunction(blockchain, 'isHubContract', [contractAddress]); - } - async isAssetStorageContract(blockchain, contractAddress) { return this.callImplementationFunction(blockchain, 'isAssetStorageContract', [ contractAddress, ]); } - async getNodeStake(blockchain, identityId) { - return this.callImplementationFunction(blockchain, 'getNodeStake', [identityId]); - } - async getBlockNumber(blockchain) { return this.callImplementationFunction(blockchain, 'getBlockNumber'); } @@ -141,13 +133,6 @@ class BlockchainModuleManager extends BaseModuleManager { ]); } - async getAssertionIdsLength(blockchain, assetContractAddress, tokenId) { - return this.callImplementationFunction(blockchain, 'getAssertionIdsLength', [ - assetContractAddress, - tokenId, - ]); - } - async getKnowledgeAssetOwner(blockchain, assetContractAddress, tokenId) { return this.callImplementationFunction(blockchain, 'getKnowledgeAssetOwner', [ assetContractAddress, @@ -159,10 +144,6 @@ class BlockchainModuleManager extends BaseModuleManager { return this.callImplementationFunction(blockchain, 'getUnfinalizedState', [tokenId]); } - async getAssertionIssuer(blockchain, assertionId) { - return this.callImplementationFunction(blockchain, 'getAssertionIssuer', [assertionId]); - } - async getShardingTableHead(blockchain) { return this.callImplementationFunction(blockchain, 'getShardingTableHead'); } @@ -402,10 +383,6 @@ class BlockchainModuleManager extends BaseModuleManager { return this.callImplementationFunction(blockchain, 'isHashFunction', [hashFunctionId]); } - async isScoreFunction(blockchain, scoreFunctionId) { - return this.callImplementationFunction(blockchain, 'isScoreFunction', [scoreFunctionId]); - } - async callScoreFunction(blockchain, scoreFunctionId, hashFunctionId, peerId, keyword, stake) { return this.callImplementationFunction(blockchain, 'callScoreFunction', [ scoreFunctionId, diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 34388a071c..147347d16e 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -301,9 +301,19 @@ class Web3Service { } fromSolidityType(solidityType, parameterValue) { - return SOLIDITY_TYPES_MAP[solidityType] - ? SOLIDITY_TYPES_MAP[solidityType](parameterValue) - : parameterValue; + const arrayMatch = solidityType.match(/^(.+)\[(\d+)\]$/); + if (arrayMatch) { + const elementType = arrayMatch[1]; + const arraySize = parseInt(arrayMatch[2], 10); + if (SOLIDITY_TYPES_MAP[elementType]) { + return Array.from({ length: arraySize }, (_, index) => + SOLIDITY_TYPES_MAP[elementType](parameterValue[index]), + ); + } + } else if (SOLIDITY_TYPES_MAP[solidityType]) { + return SOLIDITY_TYPES_MAP[solidityType](parameterValue); + } + return parameterValue; } initializeContract(contractName, contractAddress) { @@ -369,16 +379,9 @@ class Web3Service { } async getIdentityId() { - if (this.config.identityId) { - return this.config.identityId; - } - const identityId = await this.callContractFunction( - this.IdentityStorageContract, - 'getIdentityId', - [this.getPublicKey()], - ); - this.config.identityId = Number(identityId); - return this.config.identityId; + return this.callContractFunction(this.IdentityStorageContract, 'getIdentityId', [ + this.getPublicKey(), + ]); } async identityIdExists() { @@ -446,7 +449,18 @@ class Web3Service { try { if (!result) { - result = await contractInstance[functionName](...args); + const rawResult = await contractInstance[functionName](...args); + + const functionABI = contractInstance.interface.getFunction(functionName); + + const castedResults = Array.isArray(rawResult) ? rawResult : [rawResult]; + for (let i = 0; i < functionABI.outputs.length; i += 1) { + const outputType = functionABI.outputs[i].type; + castedResults[i] = this.fromSolidityType(outputType, castedResults[i]); + } + + result = castedResults.length === 1 ? castedResults[0] : castedResults; + if (contractName) { this.setContractCallCache(contractName, functionName, result); } @@ -764,22 +778,12 @@ class Web3Service { return timestamp < timestampThirtyDaysInPast; } - async isHubContract(contractAddress) { - return this.callContractFunction(this.HubContract, 'isContract(address)', [ - contractAddress, - ]); - } - async isAssetStorageContract(contractAddress) { return this.callContractFunction(this.HubContract, 'isAssetStorage(address)', [ contractAddress, ]); } - async getNodeStake(identityId) { - return this.callContractFunction(this.StakingStorageContract, 'totalStakes', [identityId]); - } - async getAssertionIdByIndex(assetContractAddress, tokenId, index) { const assetStorageContractInstance = this.assetStorageContracts[assetContractAddress.toLowerCase()]; @@ -822,17 +826,6 @@ class Web3Service { ]); } - async getAssertionIdsLength(assetContractAddress, tokenId) { - const assetStorageContractInstance = - this.assetStorageContracts[assetContractAddress.toString().toLowerCase()]; - if (!assetStorageContractInstance) - throw new Error('Unknown asset storage contract address'); - - return this.callContractFunction(assetStorageContractInstance, 'getAssertionIdsLength', [ - tokenId, - ]); - } - async getKnowledgeAssetOwner(assetContractAddress, tokenId) { const assetStorageContractInstance = this.assetStorageContracts[assetContractAddress.toString().toLowerCase()]; @@ -850,55 +843,34 @@ class Web3Service { ); } - async getAssertionIssuer(assertionId) { - return this.callContractFunction(this.AssertionStorageContract, 'getAssertionIssuer', [ - assertionId, - ]); - } - async getAgreementData(agreementId) { - const result = await this.callContractFunction( + return this.callContractFunction( this.ServiceAgreementStorageProxyContract, 'getAgreementData', [agreementId], ); - - return { - startTime: result['0'].toNumber(), - epochsNumber: result['1'], - epochLength: result['2'].toNumber(), - tokenAmount: result['3'][0], - updateTokenAmount: result['3'][1], - scoreFunctionId: result['4'][0], - proofWindowOffsetPerc: result['4'][1], - }; } async getAssertionSize(assertionId) { - const assertionSize = await this.callContractFunction( - this.AssertionStorageContract, - 'getAssertionSize', - [assertionId], - ); - return Number(assertionSize); + return this.callContractFunction(this.AssertionStorageContract, 'getAssertionSize', [ + assertionId, + ]); } async getAssertionTriplesNumber(assertionId) { - const assertionTriplesNumber = await this.callContractFunction( + return this.callContractFunction( this.AssertionStorageContract, 'getAssertionTriplesNumber', [assertionId], ); - return Number(assertionTriplesNumber); } async getAssertionChunksNumber(assertionId) { - const assertionChunksNumber = await this.callContractFunction( + return this.callContractFunction( this.AssertionStorageContract, 'getAssertionChunksNumber', [assertionId], ); - return Number(assertionChunksNumber); } selectCommitManagerContract(latestStateIndex) { @@ -944,43 +916,39 @@ class Web3Service { } async getR2() { - const r2 = await this.callContractFunction( + return this.callContractFunction( this.ParametersStorageContract, 'r2', [], 'ParametersStorageContract', ); - return r2; } async getR1() { - const r1 = await this.callContractFunction( + return this.callContractFunction( this.ParametersStorageContract, 'r1', [], 'ParametersStorageContract', ); - return r1; } async getR0() { - const r0 = await this.callContractFunction( + return this.callContractFunction( this.ParametersStorageContract, 'r0', [], 'ParametersStorageContract', ); - return r0; } async getFinalizationCommitsNumber() { - const finalizationCommitsNumber = await this.callContractFunction( + return this.callContractFunction( this.ParametersStorageContract, 'finalizationCommitsNumber', [], 'ParametersStorageContract', ); - return finalizationCommitsNumber; } submitCommit( @@ -1073,12 +1041,7 @@ class Web3Service { } async getShardingTableLength() { - const nodesCount = await this.callContractFunction( - this.ShardingTableStorageContract, - 'nodesCount', - [], - ); - return Number(nodesCount); + return this.callContractFunction(this.ShardingTableStorageContract, 'nodesCount', []); } async getShardingTablePage(startingIdentityId, nodesNum) { @@ -1146,23 +1109,21 @@ class Web3Service { } async getUpdateCommitWindowDuration() { - const commitWindowDurationPerc = await this.callContractFunction( + return this.callContractFunction( this.ParametersStorageContract, 'updateCommitWindowDuration', [], 'ParametersStorageContract', ); - return Number(commitWindowDurationPerc); } async getCommitWindowDurationPerc() { - const commitWindowDurationPerc = await this.callContractFunction( + return this.callContractFunction( this.ParametersStorageContract, 'commitWindowDurationPerc', [], 'ParametersStorageContract', ); - return Number(commitWindowDurationPerc); } async getProofWindowDurationPerc() { @@ -1175,13 +1136,12 @@ class Web3Service { } async getEpochLength() { - const epochLength = await this.callContractFunction( + return this.callContractFunction( this.ParametersStorageContract, 'epochLength', [], 'ParametersStorageContract', ); - return Number(epochLength); } async isHashFunction(hashFunctionId) { @@ -1190,12 +1150,6 @@ class Web3Service { ]); } - async isScoreFunction(scoreFunctionId) { - return this.callContractFunction(this.ScoringProxyContract, 'isScoreFunction(uint8)', [ - scoreFunctionId, - ]); - } - async callScoreFunction(scoreFunctionId, hashFunctionId, peerId, keyword, stake) { return this.callContractFunction(this.ScoringProxyContract, 'callScoreFunction', [ scoreFunctionId, From 5f7fe791a30a53098ba4e88777c831782b051ea3 Mon Sep 17 00:00:00 2001 From: Uladzislau Hubar Date: Fri, 15 Dec 2023 04:29:57 +0100 Subject: [PATCH 11/13] Reverted back solidity types casting in 'callContractFunction', fixed type casting in the blockchain event listener --- src/constants/constants.js | 11 --- .../blockchain/implementation/web3-service.js | 92 +++++++++++-------- .../blockchain-event-listener-service.js | 1 + 3 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/constants/constants.js b/src/constants/constants.js index 3158469986..6c6b1139ef 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -592,18 +592,7 @@ export const BLOCK_TIME_MILLIS = { export const TRANSACTION_CONFIRMATIONS = 1; export const SOLIDITY_TYPES_MAP = { - uint8: (value) => Number(value), - uint16: (value) => Number(value), - uint32: (value) => Number(value), - uint72: (value) => Number(value), - uint96: (value) => Number(value), - uint128: (value) => Number(value), uint256: (value) => Number(value), - - 'uint8[]': (values) => values.map((value) => Number(value)), - 'uint32[]': (values) => values.map((value) => Number(value)), - 'uint96[]': (values) => values.map((value) => Number(value)), - 'uint256[]': (values) => values.map((value) => Number(value)), }; export const CACHED_CONTRACT_CALLS = { diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 147347d16e..d2cc1ec7fe 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -301,19 +301,9 @@ class Web3Service { } fromSolidityType(solidityType, parameterValue) { - const arrayMatch = solidityType.match(/^(.+)\[(\d+)\]$/); - if (arrayMatch) { - const elementType = arrayMatch[1]; - const arraySize = parseInt(arrayMatch[2], 10); - if (SOLIDITY_TYPES_MAP[elementType]) { - return Array.from({ length: arraySize }, (_, index) => - SOLIDITY_TYPES_MAP[elementType](parameterValue[index]), - ); - } - } else if (SOLIDITY_TYPES_MAP[solidityType]) { - return SOLIDITY_TYPES_MAP[solidityType](parameterValue); - } - return parameterValue; + return SOLIDITY_TYPES_MAP[solidityType] + ? SOLIDITY_TYPES_MAP[solidityType](parameterValue) + : parameterValue; } initializeContract(contractName, contractAddress) { @@ -379,9 +369,12 @@ class Web3Service { } async getIdentityId() { - return this.callContractFunction(this.IdentityStorageContract, 'getIdentityId', [ - this.getPublicKey(), - ]); + const identityId = await this.callContractFunction( + this.IdentityStorageContract, + 'getIdentityId', + [this.getPublicKey()], + ); + return Number(identityId); } async identityIdExists() { @@ -449,18 +442,7 @@ class Web3Service { try { if (!result) { - const rawResult = await contractInstance[functionName](...args); - - const functionABI = contractInstance.interface.getFunction(functionName); - - const castedResults = Array.isArray(rawResult) ? rawResult : [rawResult]; - for (let i = 0; i < functionABI.outputs.length; i += 1) { - const outputType = functionABI.outputs[i].type; - castedResults[i] = this.fromSolidityType(outputType, castedResults[i]); - } - - result = castedResults.length === 1 ? castedResults[0] : castedResults; - + result = await contractInstance[functionName](...args); if (contractName) { this.setContractCallCache(contractName, functionName, result); } @@ -826,6 +808,17 @@ class Web3Service { ]); } + async getAssertionIdsLength(assetContractAddress, tokenId) { + const assetStorageContractInstance = + this.assetStorageContracts[assetContractAddress.toString().toLowerCase()]; + if (!assetStorageContractInstance) + throw new Error('Unknown asset storage contract address'); + + return this.callContractFunction(assetStorageContractInstance, 'getAssertionIdsLength', [ + tokenId, + ]); + } + async getKnowledgeAssetOwner(assetContractAddress, tokenId) { const assetStorageContractInstance = this.assetStorageContracts[assetContractAddress.toString().toLowerCase()]; @@ -844,33 +837,48 @@ class Web3Service { } async getAgreementData(agreementId) { - return this.callContractFunction( + const result = await this.callContractFunction( this.ServiceAgreementStorageProxyContract, 'getAgreementData', [agreementId], ); + + return { + startTime: result['0'].toNumber(), + epochsNumber: result['1'], + epochLength: result['2'].toNumber(), + tokenAmount: result['3'][0], + updateTokenAmount: result['3'][1], + scoreFunctionId: result['4'][0], + proofWindowOffsetPerc: result['4'][1], + }; } async getAssertionSize(assertionId) { - return this.callContractFunction(this.AssertionStorageContract, 'getAssertionSize', [ - assertionId, - ]); + const assertionSize = await this.callContractFunction( + this.AssertionStorageContract, + 'getAssertionSize', + [assertionId], + ); + return Number(assertionSize); } async getAssertionTriplesNumber(assertionId) { - return this.callContractFunction( + const assertionTriplesNumber = await this.callContractFunction( this.AssertionStorageContract, 'getAssertionTriplesNumber', [assertionId], ); + return Number(assertionTriplesNumber); } async getAssertionChunksNumber(assertionId) { - return this.callContractFunction( + const assertionChunksNumber = await this.callContractFunction( this.AssertionStorageContract, 'getAssertionChunksNumber', [assertionId], ); + return Number(assertionChunksNumber); } selectCommitManagerContract(latestStateIndex) { @@ -1041,7 +1049,12 @@ class Web3Service { } async getShardingTableLength() { - return this.callContractFunction(this.ShardingTableStorageContract, 'nodesCount', []); + const nodesCount = await this.callContractFunction( + this.ShardingTableStorageContract, + 'nodesCount', + [], + ); + return Number(nodesCount); } async getShardingTablePage(startingIdentityId, nodesNum) { @@ -1109,21 +1122,23 @@ class Web3Service { } async getUpdateCommitWindowDuration() { - return this.callContractFunction( + const commitWindowDurationPerc = await this.callContractFunction( this.ParametersStorageContract, 'updateCommitWindowDuration', [], 'ParametersStorageContract', ); + return Number(commitWindowDurationPerc); } async getCommitWindowDurationPerc() { - return this.callContractFunction( + const commitWindowDurationPerc = await this.callContractFunction( this.ParametersStorageContract, 'commitWindowDurationPerc', [], 'ParametersStorageContract', ); + return Number(commitWindowDurationPerc); } async getProofWindowDurationPerc() { @@ -1136,12 +1151,13 @@ class Web3Service { } async getEpochLength() { - return this.callContractFunction( + const epochLength = await this.callContractFunction( this.ParametersStorageContract, 'epochLength', [], 'ParametersStorageContract', ); + return Number(epochLength); } async isHashFunction(hashFunctionId) { diff --git a/src/service/blockchain-event-listener-service.js b/src/service/blockchain-event-listener-service.js index d19bd59393..3cf9afcc4a 100644 --- a/src/service/blockchain-event-listener-service.js +++ b/src/service/blockchain-event-listener-service.js @@ -261,6 +261,7 @@ class BlockchainEventListenerService { ).type; const castedParameterValue = this.blockchainModuleManager.fromSolidityType( + blockchainId, parameterSolidityType, parameterValue, ); From 483ef33324b5eacfd6836e0202dc06f856db0539 Mon Sep 17 00:00:00 2001 From: Djordje Kovacevic Date: Mon, 25 Dec 2023 11:31:13 +0100 Subject: [PATCH 12/13] Reading contract names from parameters storage --- .../blockchain/implementation/web3-service.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index d2cc1ec7fe..768d60c426 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -21,6 +21,7 @@ import { FALLBACK_PROVIDER_QUORUM, RPC_PROVIDER_STALL_TIMEOUT, CACHED_CONTRACT_CALLS, + CONTRACTS, } from '../../../constants/constants.js'; const require = createRequire(import.meta.url); @@ -928,7 +929,7 @@ class Web3Service { this.ParametersStorageContract, 'r2', [], - 'ParametersStorageContract', + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, ); } @@ -937,7 +938,7 @@ class Web3Service { this.ParametersStorageContract, 'r1', [], - 'ParametersStorageContract', + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, ); } @@ -946,7 +947,7 @@ class Web3Service { this.ParametersStorageContract, 'r0', [], - 'ParametersStorageContract', + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, ); } @@ -955,7 +956,7 @@ class Web3Service { this.ParametersStorageContract, 'finalizationCommitsNumber', [], - 'ParametersStorageContract', + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, ); } @@ -1126,7 +1127,7 @@ class Web3Service { this.ParametersStorageContract, 'updateCommitWindowDuration', [], - 'ParametersStorageContract', + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, ); return Number(commitWindowDurationPerc); } @@ -1136,7 +1137,7 @@ class Web3Service { this.ParametersStorageContract, 'commitWindowDurationPerc', [], - 'ParametersStorageContract', + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, ); return Number(commitWindowDurationPerc); } @@ -1146,7 +1147,7 @@ class Web3Service { this.ParametersStorageContract, 'proofWindowDurationPerc', [], - 'ParametersStorageContract', + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, ); } @@ -1155,7 +1156,7 @@ class Web3Service { this.ParametersStorageContract, 'epochLength', [], - 'ParametersStorageContract', + CONTRACTS.PARAMETERS_STORAGE_CONTRACT, ); return Number(epochLength); } @@ -1181,7 +1182,7 @@ class Web3Service { this.scoringFunctionsContracts[1], 'getParameters', [], - 'Log2PLDSFContract', + CONTRACTS.LOG2PLDSF, ); const params = {}; From 29f52cfd320ba09d21d8735ea9296185acdcef1c Mon Sep 17 00:00:00 2001 From: Djordje Kovacevic Date: Mon, 25 Dec 2023 11:35:46 +0100 Subject: [PATCH 13/13] Added caching for identity id --- src/constants/constants.js | 2 ++ src/modules/blockchain/implementation/web3-service.js | 1 + 2 files changed, 3 insertions(+) diff --git a/src/constants/constants.js b/src/constants/constants.js index 6c6b1139ef..a31ec7dca0 100644 --- a/src/constants/constants.js +++ b/src/constants/constants.js @@ -555,6 +555,7 @@ export const CONTRACTS = { COMMIT_MANAGER_V1_U1_CONTRACT: 'CommitManagerV1U1Contract', SERVICE_AGREEMENT_V1_CONTRACT: 'ServiceAgreementV1Contract', PARAMETERS_STORAGE_CONTRACT: 'ParametersStorageContract', + IDENTITY_STORAGE_CONTRACT: 'IdentityStorageContract', LOG2PLDSF: 'Log2PLDSFContract', }; @@ -607,4 +608,5 @@ export const CACHED_CONTRACT_CALLS = { 'epochLength', ]), Log2PLDSFContract: new Set(['getParameters']), + IdentityStorageContract: new Set(['getIdentityId']), }; diff --git a/src/modules/blockchain/implementation/web3-service.js b/src/modules/blockchain/implementation/web3-service.js index 768d60c426..027b1e1eed 100644 --- a/src/modules/blockchain/implementation/web3-service.js +++ b/src/modules/blockchain/implementation/web3-service.js @@ -374,6 +374,7 @@ class Web3Service { this.IdentityStorageContract, 'getIdentityId', [this.getPublicKey()], + CONTRACTS.IDENTITY_STORAGE_CONTRACT, ); return Number(identityId); }