diff --git a/src/components/Indexer/index.ts b/src/components/Indexer/index.ts index 249696e88..9b24f543b 100644 --- a/src/components/Indexer/index.ts +++ b/src/components/Indexer/index.ts @@ -223,7 +223,8 @@ export class OceanIndexer { EVENTS.DISPENSER_ACTIVATED, EVENTS.DISPENSER_DEACTIVATED, EVENTS.EXCHANGE_ACTIVATED, - EVENTS.EXCHANGE_DEACTIVATED + EVENTS.EXCHANGE_DEACTIVATED, + EVENTS.EXCHANGE_RATE_CHANGED ].includes(event.method) ) { // will emit the metadata created/updated event and advertise it to the other peers (on create only) diff --git a/src/components/Indexer/processor.ts b/src/components/Indexer/processor.ts index 6bf64a0e6..f25f93f88 100644 --- a/src/components/Indexer/processor.ts +++ b/src/components/Indexer/processor.ts @@ -1017,7 +1017,10 @@ export class DispenserDeactivatedEventProcessor extends BaseEventProcessor { const index = stat.prices.indexOf(price) stat.prices.splice(index, 1) break - } else if (!doesDispenserAlreadyExist(event.address, stat.prices)[0]) { + } else if ( + stat.datatokenAddress.toLowerCase() === datatokenAddress.toLowerCase() && + !doesDispenserAlreadyExist(event.address, stat.prices)[0] + ) { INDEXER_LOGGER.logMessage( `Detected DispenserDeactivated changed for ${event.address}, but dispenser does not exist in the DDO pricing.` ) @@ -1184,7 +1187,10 @@ export class ExchangeDeactivatedEventProcessor extends BaseEventProcessor { const index = stat.prices.indexOf(price) stat.prices.splice(index, 1) break - } else if (!doesFreAlreadyExist(exchangeId, stat.prices)[0]) { + } else if ( + stat.datatokenAddress.toLowerCase() === datatokenAddress.toLowerCase() && + !doesFreAlreadyExist(exchangeId, stat.prices)[0] + ) { INDEXER_LOGGER.logMessage( `Detected ExchangeDeactivated changed for ${event.address}, but exchange ${exchangeId} does not exist in the DDO pricing.` ) @@ -1218,3 +1224,82 @@ export class ExchangeDeactivatedEventProcessor extends BaseEventProcessor { } } } +export class ExchangeRateChangedEventProcessor extends BaseEventProcessor { + async processEvent( + event: ethers.Log, + chainId: number, + signer: Signer, + provider: JsonRpcApiProvider + ): Promise { + const decodedEventData = await this.getEventData( + provider, + event.transactionHash, + FixedRateExchange.abi + ) + const exchangeId = ethers.toUtf8Bytes(decodedEventData.args[0].toString()) + const newRate = decodedEventData.args[2].toString() + const freContract = new ethers.Contract(event.address, FixedRateExchange.abi, signer) + const exchange = await freContract.getExchange(exchangeId) + const datatokenAddress = exchange[1] + const datatokenContract = getDtContract(signer, datatokenAddress) + const nftAddress = await datatokenContract.getERC721Address() + const did = + 'did:op:' + + createHash('sha256') + .update(getAddress(nftAddress) + chainId.toString(10)) + .digest('hex') + try { + const { ddo: ddoDatabase } = await getDatabase() + const ddo = await ddoDatabase.retrieve(did) + if (!ddo) { + INDEXER_LOGGER.logMessage( + `Detected ExchangeRateChanged changed for ${did}, but it does not exists.` + ) + return + } + if (!ddo.indexedMetadata) { + ddo.indexedMetadata = {} + } + + if (!Array.isArray(ddo.indexedMetadata.stats)) { + ddo.indexedMetadata.stats = [] + } + if (ddo.indexedMetadata.stats.length !== 0) { + for (const stat of ddo.indexedMetadata.stats) { + if ( + stat.datatokenAddress.toLowerCase() === datatokenAddress.toLowerCase() && + doesFreAlreadyExist(exchangeId, stat.prices)[0] + ) { + const price = doesFreAlreadyExist(exchangeId, stat.prices)[1] + price.price = newRate + break + } else { + INDEXER_LOGGER.logMessage(`[ExchangeRateChanged] - Could not find the exchange in DDO ${did} prices`) + return + } + } + } else { + INDEXER_LOGGER.logMessage(`[ExchangeRateChanged] - No stats were found on the ddo`) + const serviceIdToFind = findServiceIdByDatatoken(ddo, datatokenAddress) + if (serviceIdToFind === '') { + INDEXER_LOGGER.logMessage( + `[ExchangeRateChanged] - This datatoken does not contain this service. Invalid service id!` + ) + return + } + ddo.indexedMetadata.stats.push({ + datatokenAddress: datatokenAddress, + name: await datatokenContract.name(), + serviceId: serviceIdToFind, + orders: 0, + prices: getPricesByDt(datatokenContract, signer) + }) + } + + const savedDDO = this.createOrUpdateDDO(ddo, EVENTS.EXCHANGE_RATE_CHANGED) + return savedDDO + } catch (err) { + INDEXER_LOGGER.log(LOG_LEVELS_STR.LEVEL_ERROR, `Error retrieving DDO: ${err}`, true) + } + } +} \ No newline at end of file diff --git a/src/components/Indexer/utils.ts b/src/components/Indexer/utils.ts index 9d3c1795f..6cfe9619e 100644 --- a/src/components/Indexer/utils.ts +++ b/src/components/Indexer/utils.ts @@ -17,7 +17,8 @@ import { OrderReusedEventProcessor, OrderStartedEventProcessor, ExchangeActivatedEventProcessor, - ExchangeDeactivatedEventProcessor + ExchangeDeactivatedEventProcessor, + ExchangeRateChangedEventProcessor } from './processor.js' import { INDEXER_LOGGER } from '../../utils/logging/common.js' import { fetchEventFromTransaction } from '../../utils/util.js' @@ -38,6 +39,7 @@ let dispenserActivatedEventProcessor: DispenserActivatedEventProcessor let dispenserDeactivatedEventProcessor: DispenserDeactivatedEventProcessor let exchangeActivatedEventProcessor: ExchangeActivatedEventProcessor let exchangeDeactivatedEventProcessor: ExchangeDeactivatedEventProcessor +let exchangeNewRateEventProcessor: ExchangeRateChangedEventProcessor function getMetadataEventProcessor(chainId: number): MetadataEventProcessor { @@ -104,6 +106,15 @@ function getExchangeDeactivatedEventProcessor( return exchangeDeactivatedEventProcessor } +function getExchangeNewRateEventProcessor( + chainId: number +) { + if(!exchangeNewRateEventProcessor) { + exchangeNewRateEventProcessor = new ExchangeRateChangedEventProcessor(chainId) + } + return exchangeNewRateEventProcessor +} + export const getContractAddress = (chainId: number, contractName: string): string => { const addressFile = getOceanArtifactsAdressesByChainId(chainId) if (addressFile && contractName in addressFile) { @@ -255,7 +266,13 @@ export const processChunkLogs = async ( } else if (event.type === EVENTS.EXCHANGE_CREATED) { storeEvents[event.type] = procesExchangeCreated() } else if (event.type === EVENTS.EXCHANGE_RATE_CHANGED) { - storeEvents[event.type] = processExchangeRateChanged() + const processor = getExchangeNewRateEventProcessor(chainId) + storeEvents[event.type] = await processor.processEvent( + log, + chainId, + signer, + provider + ) } else if (event.type === EVENTS.ORDER_STARTED) { const processor = getOrderStartedEventProcessor(chainId) storeEvents[event.type] = await processor.processEvent( @@ -319,10 +336,6 @@ const procesExchangeCreated = (): string => { return 'EXCHANGE_CREATED' } -const processExchangeRateChanged = (): string => { - return 'EXCHANGE_RATE_CHANGED' -} - const processTokenUriUpadate = (): string => { return 'TOKEN_URI_UPDATE' }