diff --git a/src/services/crawl-tx/crawl_tx.service.ts b/src/services/crawl-tx/crawl_tx.service.ts index 156fa3b97..318171a1a 100644 --- a/src/services/crawl-tx/crawl_tx.service.ts +++ b/src/services/crawl-tx/crawl_tx.service.ts @@ -333,58 +333,241 @@ export default class CrawlTxService extends BullableService { this.logger.debug('result insert tx', resultInsertGraph); } - private setMsgIndexToEvent(tx: any) { - const mapEventMsgIdx: Map = new Map(); + public mappingFlatEventToLog( + eventHasIndex: any, + eventEncodedFlat: any, + indexMsg: number + ) { + const attributesInEvent = eventHasIndex.attributes; + // i, j are index of eventHasIndex and eventEncodedFlat + let i = 0; + let j = 0; + while (i < attributesInEvent.length && j < eventEncodedFlat.length) { + // find last element with same eventIndex + let lastIndexSameEvent = j; + while ( + lastIndexSameEvent < eventEncodedFlat.length && + eventEncodedFlat[lastIndexSameEvent].indexEvent === + eventEncodedFlat[j].indexEvent + ) { + lastIndexSameEvent += 1; + } - // set index_msg from log to mapEventMsgIdx - tx.tx_response.logs?.forEach((log: any, index: number) => { - log.events.forEach((event: any) => { - const { type } = event; - event.attributes.forEach((attribute: any) => { - const keyInMap = `${type}_${attribute.key}_${attribute.value}`; - if (mapEventMsgIdx.has(keyInMap)) { - const listIndex = mapEventMsgIdx.get(keyInMap); - listIndex?.push(index); - } else { - mapEventMsgIdx.set(keyInMap, [index]); + if ( + attributesInEvent[i].key === eventEncodedFlat[j].key && + attributesInEvent[i].value === eventEncodedFlat[j].value + ) { + const isEventMapped = eventEncodedFlat + .slice(j, lastIndexSameEvent) + // eslint-disable-next-line @typescript-eslint/no-loop-func, no-inner-declarations + .every((item: any, index: number) => { + if ( + attributesInEvent[i + index].key === item.key && + attributesInEvent[i + index].value === item.value + ) { + return true; + } + return false; + }); + if (isEventMapped) { + // mark event encoded to be mapped + for (let k = j; k < lastIndexSameEvent; k += 1) { + // eslint-disable-next-line no-param-reassign + eventEncodedFlat[k].indexMapped = indexMsg; } - }); - }); + i += lastIndexSameEvent - j; + } + } + j = lastIndexSameEvent; + } + } + + // self check msg index by counting event + private selfCheckByAnotherWay(tx: any) { + // count total attribute for each message, countAttributeInEvent[i] = x mean message i has x attributes + const countAttributeInEvent: number[] = []; + tx.tx_response.logs.forEach((log: any) => { + const countAttribute = log.events.reduce( + (acc: number, curr: any) => acc + curr.attributes.length, + 0 + ); + countAttributeInEvent.push(countAttribute); }); - // set index_msg from mapEventMsgIdx to event - tx.tx_response.events.forEach((event: any) => { - const { type } = event; - event.attributes.forEach((attribute: any) => { - const key = attribute?.key - ? fromUtf8(fromBase64(attribute?.key)) - : null; - const value = attribute?.value - ? fromUtf8(fromBase64(attribute?.value)) - : null; - const keyInMap = `${type}_${key}_${value}`; - - const listIndex = mapEventMsgIdx.get(keyInMap); - // get first index with this key - const firstIndex = listIndex?.shift(); - - if (firstIndex != null) { - if (event.msg_index && event.msg_index !== firstIndex) { - this.logger.warn( - `something wrong: setting index ${firstIndex} to existed index ${event.msg_index}` - ); - } else { - // eslint-disable-next-line no-param-reassign - event.msg_index = firstIndex; - } + let reachLastEventTypeTx = false; + let countCurrentAttribute = 0; + let currentCompareEventId = 0; + for (let i = 0; i < tx.tx_response.events.length; i += 1) { + if (tx.tx_response.events[i].type === 'tx') { + reachLastEventTypeTx = true; + } + if (reachLastEventTypeTx && tx.tx_response.events[i].type !== 'tx') { + if ( + countCurrentAttribute < countAttributeInEvent[currentCompareEventId] + ) { + countCurrentAttribute += tx.tx_response.events[i].attributes.length; } - // delete key in map if value is empty - if (listIndex?.length === 0) { - mapEventMsgIdx.delete(keyInMap); + // after count, check if count is equal countAttributeInEvent[currentCompareEventId] or not + if ( + countCurrentAttribute === countAttributeInEvent[currentCompareEventId] + ) { + // if true, count success, then next currentCompareEventId and reset count = 0 + currentCompareEventId += 1; + countCurrentAttribute = 0; + } else if ( + countCurrentAttribute > countAttributeInEvent[currentCompareEventId] + ) { + this.logger.warn('Count event in log is not equal event encoded'); + return false; + } + } + } + return true; + } + + private checkMappingEventToLog(tx: any) { + this.logger.info('checking mapping log in tx :', tx.tx_response.txhash); + let flattenLog: string[] = []; + let flattenEventEncoded: string[] = []; + + tx?.tx_response?.logs.forEach((log: any, index: number) => { + log.events.forEach((event: any) => { + event.attributes.forEach((attr: any) => { + flattenLog.push(`${index}-${event.type}-${attr.key}-${attr.value}`); + }); + }); + }); + + tx?.tx_response?.events?.forEach((event: any) => { + event.attributes.forEach((attr: any) => { + if (event.msg_index !== undefined) { + const key = attr.key ? fromUtf8(fromBase64(attr.key)) : null; + const value = attr.value ? fromUtf8(fromBase64(attr.value)) : null; + flattenEventEncoded.push( + `${event.msg_index}-${event.type}-${key}-${value}` + ); } }); }); + // compare 2 array + if (flattenLog.length !== flattenEventEncoded.length) { + this.logger.warn('Length between 2 flatten array is not equal'); + } + flattenLog = flattenLog.sort(); + flattenEventEncoded = flattenEventEncoded.sort(); + const checkResult = flattenLog.every( + (item: string, index: number) => item === flattenEventEncoded[index] + ); + if (checkResult === false) { + this.logger.warn('Mapping event to log is wrong'); + } + } + + private setMsgIndexToEvent(tx: any) { + /*------ + DO NOT USE CURRENTLY + MAPPING BY ORDER IN EVENT AND LOG + THIS CASE BASED ON ORDER NOT CHANGED BETWEEN EVENT AND LOG + --------*/ + // // flatten event and decode key value + // const eventEncodedFlats: any[] = []; + // tx.tx_response.events.forEach((event: any, index: number) => { + // event.attributes.forEach((attr: any) => { + // eventEncodedFlats.push({ + // ...{ + // key: attr.key ? fromUtf8(fromBase64(attr.key)) : null, + // value: attr.value ? fromUtf8(fromBase64(attr.value)) : null, + // }, + // indexEvent: index, + // type: event.type, + // }); + // }); + // }); + // // loop logs (has order for each messages) + // tx.tx_response.logs.forEach((log: any, index: number) => { + // // loop each event in log to compare with event encoded + // log.events.forEach((eventInLog: any) => { + // // filter list event has type equal eventInLog.type and not be setted index msg + // const filtedEventByTypeFlat = eventEncodedFlats.filter( + // (eventEncoded: any) => + // eventEncoded.type === eventInLog.type && + // eventEncoded.msg_index === undefined + // ); + // // mapping between log and event + // this.mappingFlatEventToLog(eventInLog, filtedEventByTypeFlat, index); + // }); + // }); + // // set index msg to event encoded + // eventEncodedFlats + // .filter((item: any) => item.indexMapped !== undefined) + // .forEach((item: any) => { + // if ( + // tx.tx_response.events[item.indexEvent].msg_index !== undefined && + // tx.tx_response.events[item.indexEvent].msg_index !== item.indexMapped + // ) { + // this.logger.warn( + // `something wrong: setting index ${ + // item.indexMapped + // } to existed index ${ + // tx.tx_response.eventstx.tx_response.events[item.indexEvent] + // .msg_index + // }` + // ); + // } + // // eslint-disable-next-line no-param-reassign + // tx.tx_response.events[item.indexEvent].msg_index = item.indexMapped; + // }); + // // self check msg index by counting event + // const selfCheck = this.selfCheckByAnotherWay(tx); + // if (!selfCheck) { + // this.logger.warn('selfcheck fail'); + // } + + /*--------- + TESTING + MAPPING EVENT BY COUNT EACH LOG AND EVENT MUST BE SAME + -----------*/ + // count total attribute for each message, countAttributeInEvent[i] = x mean message i has x attributes + const countAttributeInEvent: number[] = tx?.tx_response?.logs?.map( + (log: any) => + log.events.reduce( + (acc: number, curr: any) => acc + curr.attributes.length, + 0 + ) + ); + + let reachLastEventTypeTx = false; + let countCurrentAttribute = 0; + let currentCompareEventId = 0; + for (let i = 0; i < tx?.tx_response?.events?.length; i += 1) { + if (tx.tx_response.events[i].type === 'tx') { + reachLastEventTypeTx = true; + } + if (reachLastEventTypeTx && tx.tx_response.events[i].type !== 'tx') { + if ( + countCurrentAttribute < countAttributeInEvent[currentCompareEventId] + ) { + countCurrentAttribute += tx.tx_response.events[i].attributes.length; + // eslint-disable-next-line no-param-reassign + tx.tx_response.events[i].msg_index = currentCompareEventId; + } + + // after count, check if count is equal countAttributeInEvent[currentCompareEventId] or not + if ( + countCurrentAttribute === countAttributeInEvent[currentCompareEventId] + ) { + // if true, count success, then next currentCompareEventId and reset count = 0 + currentCompareEventId += 1; + countCurrentAttribute = 0; + } else if ( + countCurrentAttribute > countAttributeInEvent[currentCompareEventId] + ) { + this.logger.warn('Count event in log is not equal event encoded'); + } + } + } + this.checkMappingEventToLog(tx); } private _findAttribute( diff --git a/test/unit/services/crawl-transaction/parse_transaction.spec.ts b/test/unit/services/crawl-transaction/parse_transaction.spec.ts index c72cbe542..ff785aa85 100644 --- a/test/unit/services/crawl-transaction/parse_transaction.spec.ts +++ b/test/unit/services/crawl-transaction/parse_transaction.spec.ts @@ -4,6 +4,7 @@ import { AfterEach, BeforeEach, Describe, Test } from '@jest-decorated/core'; import { ServiceBroker } from 'moleculer'; import { Log } from '@cosmjs/stargate/build/logs'; import { Attribute, Event } from '@cosmjs/stargate/build/events'; +import { fromBase64, fromUtf8 } from '@cosmjs/encoding'; import { Transaction, Event as EventModel, @@ -154,6 +155,420 @@ export default class CrawlTransactionTest { // ); } + arrDest = { + index: 3, + type: 'coin_received', + attributes: [ + { key: 'receiver', value: 'aura162x2llsxzxmavtyuxjesceewmy4wvrp79ndcrw' }, + { key: 'amount', value: '1341uaura' }, + { key: 'authz_msg_index', value: '0' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '909uaura' }, + { key: 'authz_msg_index', value: '0' }, + { key: 'receiver', value: 'aura1ujv2gmfwrwzj504ntggqld0q5euafp76vgx5lj' }, + { key: 'amount', value: '154uaura' }, + { key: 'authz_msg_index', value: '1' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '104uaura' }, + { key: 'authz_msg_index', value: '1' }, + { key: 'receiver', value: 'aura177cgzmjve5m0je6yjukcj4mmmwj8p4dkqekglz' }, + { key: 'amount', value: '4511uaura' }, + { key: 'authz_msg_index', value: '2' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '3056uaura' }, + { key: 'authz_msg_index', value: '2' }, + { key: 'receiver', value: 'aura1rqll2d4wyylvl03ht6mhglswj46gkcr3ksvkm7' }, + { key: 'amount', value: '3617uaura' }, + { key: 'authz_msg_index', value: '3' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '2451uaura' }, + { key: 'authz_msg_index', value: '3' }, + { key: 'receiver', value: 'aura1a6x0znjhztz73tq07gjvzt9ru99866jm665w9p' }, + { key: 'amount', value: '5417uaura' }, + { key: 'authz_msg_index', value: '4' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '3670uaura' }, + { key: 'authz_msg_index', value: '4' }, + { key: 'receiver', value: 'aura1q93xkwtfv7nut0eqjjws377wkjk97265zsxlx6' }, + { key: 'amount', value: '30uaura' }, + { key: 'authz_msg_index', value: '5' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '20uaura' }, + { key: 'authz_msg_index', value: '5' }, + { key: 'receiver', value: 'aura1xk6nnn0gen9n9fduz0t3twyzt8c2uzedy2545a' }, + { key: 'amount', value: '2797uaura' }, + { key: 'authz_msg_index', value: '6' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '1895uaura' }, + { key: 'authz_msg_index', value: '6' }, + { key: 'receiver', value: 'aura1f3qxww8pnx0xrea7e03ffxnlau0fk5ufs3v0zj' }, + { key: 'amount', value: '2457uaura' }, + { key: 'authz_msg_index', value: '7' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '1665uaura' }, + { key: 'authz_msg_index', value: '7' }, + { key: 'receiver', value: 'aura1fwtkqe4yp652svrj5lzdu9lnykysh947msc4xq' }, + { key: 'amount', value: '2589uaura' }, + { key: 'authz_msg_index', value: '8' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '1754uaura' }, + { key: 'authz_msg_index', value: '8' }, + { key: 'receiver', value: 'aura1j6kwc05lw0p8e08ce3r5z5qlygjzu0aq095scc' }, + { key: 'amount', value: '212uaura' }, + { key: 'authz_msg_index', value: '9' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '143uaura' }, + { key: 'authz_msg_index', value: '9' }, + { key: 'receiver', value: 'aura15f6wn3nymdnhnh5ddlqletuptjag09tryrtpq5' }, + { key: 'amount', value: '1689uaura' }, + { key: 'authz_msg_index', value: '10' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '1144uaura' }, + { key: 'authz_msg_index', value: '10' }, + { key: 'receiver', value: 'aura1efq5q4uzn583nh5mauzc5cmgms53w9l6vs5dxz' }, + { key: 'amount', value: '105uaura' }, + { key: 'authz_msg_index', value: '11' }, + { key: 'receiver', value: 'aura1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3wd7dmw' }, + { key: 'amount', value: '71uaura' }, + { key: 'authz_msg_index', value: '11' }, + ], + }; + + arrSrc: any[] = [ + { + // this event not has checkedIndex because its belong to tx event + type: 'coin_received', + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTE3eHBmdmFrbTJhbWc5NjJ5bHM2Zjg0ejNrZWxsOGM1bHQwNXpmeQ==', + }, + { key: 'YW1vdW50', value: 'ODk2dWF1cmE=' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTE2MngybGxzeHp4bWF2dHl1eGplc2NlZXdteTR3dnJwNzluZGNydw==', + }, + { key: 'YW1vdW50', value: 'MTM0MXVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'MA==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'OTA5dWF1cmE=' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'MA==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTF1anYyZ21md3J3emo1MDRudGdncWxkMHE1ZXVhZnA3NnZneDVsag==', + }, + { key: 'YW1vdW50', value: 'MTU0dWF1cmE=' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'MQ==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MTA0dWF1cmE=' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'MQ==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTE3N2Nnem1qdmU1bTBqZTZ5anVrY2o0bW1td2o4cDRka3Fla2dseg==', + }, + { key: 'YW1vdW50', value: 'NDUxMXVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'Mg==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MzA1NnVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'Mg==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFycWxsMmQ0d3l5bHZsMDNodDZtaGdsc3dqNDZna2NyM2tzdmttNw==', + }, + { key: 'YW1vdW50', value: 'MzYxN3VhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'Mw==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MjQ1MXVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'Mw==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFhNngwem5qaHp0ejczdHEwN2dqdnp0OXJ1OTk4NjZqbTY2NXc5cA==', + }, + { key: 'YW1vdW50', value: 'NTQxN3VhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'NA==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MzY3MHVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'NA==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFxOTN4a3d0ZnY3bnV0MGVxamp3czM3N3drams5NzI2NXpzeGx4Ng==', + }, + { key: 'YW1vdW50', value: 'MzB1YXVyYQ==' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'NQ==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MjB1YXVyYQ==' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'NQ==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTF4azZubm4wZ2VuOW45ZmR1ejB0M3R3eXp0OGMydXplZHkyNTQ1YQ==', + }, + { key: 'YW1vdW50', value: 'Mjc5N3VhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'Ng==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MTg5NXVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'Ng==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmM3F4d3c4cG54MHhyZWE3ZTAzZmZ4bmxhdTBmazV1ZnMzdjB6ag==', + }, + { key: 'YW1vdW50', value: 'MjQ1N3VhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'Nw==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MTY2NXVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'Nw==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmd3RrcWU0eXA2NTJzdnJqNWx6ZHU5bG55a3lzaDk0N21zYzR4cQ==', + }, + { key: 'YW1vdW50', value: 'MjU4OXVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'OA==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MTc1NHVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'OA==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFqNmt3YzA1bHcwcDhlMDhjZTNyNXo1cWx5Z2p6dTBhcTA5NXNjYw==', + }, + { key: 'YW1vdW50', value: 'MjEydWF1cmE=' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'OQ==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MTQzdWF1cmE=' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'OQ==' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTE1ZjZ3bjNueW1kbmhuaDVkZGxxbGV0dXB0amFnMDl0cnlydHBxNQ==', + }, + { key: 'YW1vdW50', value: 'MTY4OXVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'MTA=' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'MTE0NHVhdXJh' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'MTA=' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFlZnE1cTR1em41ODNuaDVtYXV6YzVjbWdtczUzdzlsNnZzNWR4eg==', + }, + { key: 'YW1vdW50', value: 'MTA1dWF1cmE=' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'MTE=' }, + ], + }, + { + type: 'coin_received', + checkedIndex: 3, + attributes: [ + { + key: 'cmVjZWl2ZXI=', + value: 'YXVyYTFmbDQ4dnNubXNkemN2ODVxNWQycTR6NWFqZGhhOHl1M3dkN2Rtdw==', + }, + { key: 'YW1vdW50', value: 'NzF1YXVyYQ==' }, + { key: 'YXV0aHpfbXNnX2luZGV4', value: 'MTE=' }, + ], + }, + ]; + + @Test('Mapping event and log') + public async testMappingEventToLog() { + const eventEncodedFlats: any[] = []; + this.arrSrc.forEach((event: any, index: number) => { + event.attributes.forEach((attr: any) => { + eventEncodedFlats.push({ + ...{ + key: attr.key ? fromUtf8(fromBase64(attr.key)) : null, + value: attr.value ? fromUtf8(fromBase64(attr.value)) : null, + }, + indexEvent: index, + type: event.type, + }); + }); + }); + + this.crawlTxService?.mappingFlatEventToLog( + this.arrDest, + this.arrSrc, + this.arrDest.index + ); + + eventEncodedFlats + .filter((item: any) => item.indexMapped !== undefined) + .forEach((item: any) => { + // eslint-disable-next-line no-param-reassign + this.arrSrc[item.indexEvent].msg_index = item.indexMapped; + expect(this.arrSrc[item.indexEvent].msg_index).toEqual( + item.checkedIndex + ); + }); + } + @AfterEach() async tearDown() { this.crawlTxService?.getQueueManager().stopAll();