1+ /* eslint-disable no-await-in-loop */
2+ import { setTimeout as sleep } from 'timers/promises' ;
13import Command from '../../command.js' ;
24import {
35 CONTENT_ASSET_HASH_FUNCTION_ID ,
46 EXPECTED_TRANSACTION_ERRORS ,
7+ GET_ASSERTION_IDS_MAX_RETRY_COUNT ,
8+ GET_ASSERTION_IDS_RETRY_DELAY_IN_SECONDS ,
9+ GET_LATEST_SERVICE_AGREEMENT_BATCH_SIZE ,
10+ GET_LATEST_SERVICE_AGREEMENT_EXCLUDE_LATEST_TOKEN_ID ,
511 GET_LATEST_SERVICE_AGREEMENT_FREQUENCY_MILLS ,
612 SERVICE_AGREEMENT_SOURCES ,
713} from '../../../constants/constants.js' ;
814
9- const BATCH_SIZE = 50 ;
10-
1115class BlockchainGetLatestServiceAgreement extends Command {
1216 constructor ( ctx ) {
1317 super ( ctx ) ;
@@ -42,23 +46,32 @@ class BlockchainGetLatestServiceAgreement extends Command {
4246 ) ;
4347 let latestBlockchainTokenId ;
4448 try {
45- latestBlockchainTokenId = await this . blockchainModuleManager . getLatestTokenId (
46- blockchain ,
47- contract ,
48- ) ;
49+ latestBlockchainTokenId =
50+ Number ( await this . blockchainModuleManager . getLatestTokenId ( blockchain , contract ) ) -
51+ GET_LATEST_SERVICE_AGREEMENT_EXCLUDE_LATEST_TOKEN_ID ;
4952 } catch ( error ) {
5053 if ( error . message . includes ( EXPECTED_TRANSACTION_ERRORS . NO_MINTED_ASSETS ) ) {
5154 this . logger . info (
5255 `Get latest service agreement: No minted assets on blockchain: ${ blockchain } ` ,
5356 ) ;
5457 return ;
5558 }
56- throw error ;
59+ this . logger . error (
60+ `Unable to process agreement data for asset contract ${ contract } . Error: ${ error } ` ,
61+ ) ;
62+ return ;
5763 }
5864
5965 const latestDbTokenId =
6066 ( await this . repositoryModuleManager . getLatestServiceAgreementTokenId ( blockchain ) ) ?? 0 ;
6167
68+ if ( latestBlockchainTokenId < latestDbTokenId ) {
69+ this . logger . debug (
70+ `Get latest service agreement: No new agreements found on blockchain: ${ blockchain } .` ,
71+ ) ;
72+ return ;
73+ }
74+
6275 this . logger . debug (
6376 `Get latest service agreement: Latest token id on chain: ${ latestBlockchainTokenId } , latest token id in database: ${ latestDbTokenId } on blockchain: ${ blockchain } ` ,
6477 ) ;
@@ -75,17 +88,15 @@ class BlockchainGetLatestServiceAgreement extends Command {
7588 ) ;
7689 if (
7790 getAgreementDataPromise . length === tokenIdDifference ||
78- getAgreementDataPromise . length === BATCH_SIZE
91+ getAgreementDataPromise . length === GET_LATEST_SERVICE_AGREEMENT_BATCH_SIZE
7992 ) {
80- // eslint-disable-next-line no-await-in-loop
8193 const missingAgreements = await Promise . all ( getAgreementDataPromise ) ;
8294
83- // eslint-disable-next-line no-await-in-loop
8495 await this . repositoryModuleManager . bulkCreateServiceAgreementRecords (
8596 missingAgreements . filter ( ( agreement ) => agreement != null ) ,
8697 ) ;
8798 getAgreementDataPromise = [ ] ;
88- tokenIdDifference -= BATCH_SIZE ;
99+ tokenIdDifference -= GET_LATEST_SERVICE_AGREEMENT_BATCH_SIZE ;
89100 }
90101 }
91102 if ( latestBlockchainTokenId - latestDbTokenId !== 0 ) {
@@ -103,56 +114,76 @@ class BlockchainGetLatestServiceAgreement extends Command {
103114 contract ,
104115 hashFunctionId = CONTENT_ASSET_HASH_FUNCTION_ID ,
105116 ) {
106- this . logger . debug (
107- `Get latest service agreement: Getting agreement data for token id: ${ tokenId } on blockchain: ${ blockchain } ` ,
108- ) ;
109- const assertionIds = await this . blockchainModuleManager . getAssertionIds (
110- blockchain ,
111- contract ,
112- tokenId ,
113- ) ;
114- const keyword = await this . ualService . calculateLocationKeyword (
115- blockchain ,
116- contract ,
117- tokenId ,
118- assertionIds [ 0 ] ,
119- ) ;
120- const agreementId = await this . serviceAgreementService . generateId (
121- blockchain ,
122- contract ,
123- tokenId ,
124- keyword ,
125- hashFunctionId ,
126- ) ;
127- const agreementData = await this . blockchainModuleManager . getAgreementData (
128- blockchain ,
129- agreementId ,
130- ) ;
117+ try {
118+ this . logger . debug (
119+ `Get latest service agreement: Getting agreement data for token id: ${ tokenId } on blockchain: ${ blockchain } ` ,
120+ ) ;
121+ let assertionIds = [ ] ;
122+ let retryCount = 0 ;
123+
124+ while ( assertionIds . length === 0 ) {
125+ if ( retryCount === GET_ASSERTION_IDS_MAX_RETRY_COUNT ) {
126+ throw Error (
127+ `Get latest service agreement: Unable to get assertion ids for token id: ${ tokenId } on blockchain: ${ blockchain } ` ,
128+ ) ;
129+ }
130+ this . logger . debug (
131+ `Get latest service agreement: getting assertion ids retry ${ retryCount } for token id: ${ tokenId } on blockchain: ${ blockchain } ` ,
132+ ) ;
133+ assertionIds = await this . blockchainModuleManager . getAssertionIds (
134+ blockchain ,
135+ contract ,
136+ tokenId ,
137+ ) ;
138+ retryCount += 1 ;
139+ await sleep ( GET_ASSERTION_IDS_RETRY_DELAY_IN_SECONDS * 1000 ) ;
140+ }
131141
132- if ( ! agreementData ) {
133- this . logger . warn (
134- `Unable to fetch agreement data while processing asset created event for agreement id: ${ agreementId } , blockchain id: ${ blockchain } ` ,
142+ const keyword = await this . ualService . calculateLocationKeyword (
143+ blockchain ,
144+ contract ,
145+ tokenId ,
146+ assertionIds [ 0 ] ,
147+ ) ;
148+ const agreementId = await this . serviceAgreementService . generateId (
149+ blockchain ,
150+ contract ,
151+ tokenId ,
152+ keyword ,
153+ hashFunctionId ,
154+ ) ;
155+ const agreementData = await this . blockchainModuleManager . getAgreementData (
156+ blockchain ,
157+ agreementId ,
135158 ) ;
136- }
137159
138- const latestStateIndex = assertionIds . length - 1 ;
139-
140- return {
141- blockchainId : blockchain ,
142- assetStorageContractAddress : contract ,
143- tokenId,
144- agreementId,
145- startTime : agreementData . startTime ,
146- epochsNumber : agreementData . epochsNumber ,
147- epochLength : agreementData . epochLength ,
148- scoreFunctionId : agreementData . scoreFunctionId ,
149- stateIndex : latestStateIndex ,
150- assertionId : assertionIds [ latestStateIndex ] ,
151- hashFunctionId,
152- keyword,
153- proofWindowOffsetPerc : agreementData . proofWindowOffsetPerc ,
154- dataSource : SERVICE_AGREEMENT_SOURCES . NODE ,
155- } ;
160+ if ( ! agreementData ) {
161+ throw Error (
162+ `Get latest service agreement: Unable to fetch agreement data while processing asset created event for agreement id: ${ agreementId } , blockchain id: ${ blockchain } ` ,
163+ ) ;
164+ }
165+
166+ const latestStateIndex = assertionIds . length - 1 ;
167+
168+ return {
169+ blockchainId : blockchain ,
170+ assetStorageContractAddress : contract ,
171+ tokenId,
172+ agreementId,
173+ startTime : agreementData . startTime ,
174+ epochsNumber : agreementData . epochsNumber ,
175+ epochLength : agreementData . epochLength ,
176+ scoreFunctionId : agreementData . scoreFunctionId ,
177+ stateIndex : latestStateIndex ,
178+ assertionId : assertionIds [ latestStateIndex ] ,
179+ hashFunctionId,
180+ keyword,
181+ proofWindowOffsetPerc : agreementData . proofWindowOffsetPerc ,
182+ dataSource : SERVICE_AGREEMENT_SOURCES . NODE ,
183+ } ;
184+ } catch ( error ) {
185+ this . logger . error ( error . message ) ;
186+ }
156187 }
157188
158189 /**
0 commit comments