11import { Injectable , Logger } from '@nestjs/common' ;
22import { Contract , ContractAbi , EventLog , Web3 } from "web3" ;
3- import { TokenMetadata , TradeType } from "../types" ;
3+ import { ProtocolEvent , TokenMetadata , TradeType } from "../types" ;
44import axios from "axios" ;
55import * as process from "process" ;
66import {
@@ -27,7 +27,8 @@ export class IndexerService {
2727 private readonly web3 : Web3
2828 private readonly accountAddress : string
2929 private readonly tokenFactoryContract : Contract < ContractAbi >
30- private readonly blocksIndexingRange = 1000
30+ private readonly maxBlocksRange = 1000
31+ private readonly maxBlocksBatchSize = 5
3132
3233 constructor (
3334 private configService : ConfigService ,
@@ -37,32 +38,30 @@ export class IndexerService {
3738 ) {
3839 const rpcUrl = configService . get ( 'RPC_URL' )
3940 const contractAddress = configService . get ( 'TOKEN_FACTORY_ADDRESS' )
40- const initialBlockNumber = configService . get ( 'INDEXER_INITIAL_BLOCK_NUMBER ' )
41+ const privateKey = configService . get ( 'SERVICE_PRIVATE_KEY ' )
4142
4243 if ( ! contractAddress ) {
4344 this . logger . error ( `[TOKEN_FACTORY_ADDRESS] is missing but required, exit` )
4445 process . exit ( 1 )
4546 }
4647
47- if ( ! initialBlockNumber ) {
48- this . logger . error ( `[INDEXER_INITIAL_BLOCK_NUMBER ] is missing but required, exit` )
48+ if ( ! privateKey ) {
49+ this . logger . error ( `[SERVICE_PRIVATE_KEY ] is missing but required, exit` )
4950 process . exit ( 1 )
5051 }
5152
5253 this . logger . log ( `Starting app service, RPC_URL=${
5354 rpcUrl
5455 } , TOKEN_FACTORY_ADDRESS=${
5556 contractAddress
56- } , INDEXER_INITIAL_BLOCK_NUMBER=${
57- initialBlockNumber
5857 } `)
5958
6059 this . web3 = new Web3 ( rpcUrl ) ;
61- const account = this . web3 . eth . accounts . privateKeyToAccount ( configService . get ( 'SERVICE_PRIVATE_KEY' ) )
60+ const account = this . web3 . eth . accounts . privateKeyToAccount ( privateKey )
6261 this . accountAddress = account . address
6362 this . web3 . eth . accounts . wallet . add ( account ) ;
64- this . logger . log ( `Service account address=${ account . address } ` )
6563 this . tokenFactoryContract = new this . web3 . eth . Contract ( TokenFactoryABI , contractAddress ) ;
64+ this . logger . log ( `Service account address=${ account . address } ` )
6665 this . bootstrap ( ) . then (
6766 ( ) => {
6867 this . eventsTrackingLoop ( )
@@ -410,7 +409,7 @@ export class IndexerService {
410409 this . logger . log ( `NewCompetitionStarted: competitionId=${ competitionId } , timestamp=${ timestamp } , txnHash=${ txnHash } ` ) ;
411410 }
412411
413- private async getLatestIndexedBlockNumber ( ) {
412+ public async getLatestIndexedBlockNumber ( ) {
414413 const indexerState = await this . dataSource . manager . findOne ( IndexerState , {
415414 where : { } ,
416415 } )
@@ -478,23 +477,14 @@ export class IndexerService {
478477 } )
479478 ] ) as EventLog [ ] [ ]
480479
481- // concat and sort all events by block number and transaction index
482- const protocolEvents : { data : EventLog ; type : string } [ ] = tokenCreatedEvents
480+ return tokenCreatedEvents
483481 . map ( data => ( { type : 'create_token' , data } ) )
484482 . concat ( ...buyEvents . map ( data => ( { type : 'buy' , data } ) ) )
485483 . concat ( ...sellEvents . map ( data => ( { type : 'sell' , data } ) ) )
486484 . concat ( ...setWinnerEvents . map ( data => ( { type : 'set_winner' , data } ) ) )
487485 . concat ( ...burnAndSetWinnerEvents . map ( data => ( { type : 'burn_token_and_set_winner' , data } ) ) )
488486 . concat ( ...winnerLiquidityEvents . map ( data => ( { type : 'winner_liquidity' , data } ) ) )
489487 . concat ( ...newCompetitionEvents . map ( data => ( { type : 'new_competition' , data } ) ) )
490- . sort ( ( a , b ) => {
491- const blockNumberDiff = Number ( a . data . blockNumber ) - Number ( b . data . blockNumber )
492- if ( blockNumberDiff !== 0 ) {
493- return blockNumberDiff
494- }
495- return Number ( a . data . transactionIndex ) - Number ( b . data . transactionIndex )
496- } )
497- return protocolEvents
498488 }
499489
500490 async eventsTrackingLoop ( ) {
@@ -506,13 +496,34 @@ export class IndexerService {
506496
507497 try {
508498 const blockchainBlockNumber = + ( String ( await this . web3 . eth . getBlockNumber ( ) ) )
509- toBlock = fromBlock + this . blocksIndexingRange - 1
499+ toBlock = fromBlock + this . maxBlocksRange * this . maxBlocksBatchSize - 1
510500 if ( toBlock > blockchainBlockNumber ) {
511501 toBlock = blockchainBlockNumber
512502 }
513503
514504 if ( toBlock - fromBlock >= 1 ) {
515- const protocolEvents = await this . getEventsFromBlocksRange ( fromBlock , toBlock )
505+ const delta = toBlock - fromBlock
506+ const numberOfBatches = Math . ceil ( delta / this . maxBlocksRange )
507+
508+ const protocolEventsBatch = await Promise . all (
509+ new Array ( numberOfBatches )
510+ . fill ( null )
511+ . map ( async ( _ , index , arr ) => {
512+ const batchFromBlock = fromBlock + index * this . maxBlocksRange
513+ const batchToBlock = Math . min ( batchFromBlock + this . maxBlocksRange , toBlock )
514+ return await this . getEventsFromBlocksRange ( batchFromBlock , batchToBlock )
515+ } )
516+ )
517+
518+ const protocolEvents = protocolEventsBatch
519+ . flat ( )
520+ . sort ( ( a , b ) => {
521+ const blockNumberDiff = Number ( a . data . blockNumber ) - Number ( b . data . blockNumber )
522+ if ( blockNumberDiff !== 0 ) {
523+ return blockNumberDiff
524+ }
525+ return Number ( a . data . transactionIndex ) - Number ( b . data . transactionIndex )
526+ } )
516527
517528 await this . dataSource . manager . transaction ( async ( transactionalEntityManager ) => {
518529 for ( const protocolEvent of protocolEvents ) {
0 commit comments