Skip to content

Commit

Permalink
feat: erc20 reindex too big contract (#879)
Browse files Browse the repository at this point in the history
  • Loading branch information
phamphong9981 authored Aug 5, 2024
1 parent 1d85aba commit 5f1fbe8
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 52 deletions.
5 changes: 4 additions & 1 deletion ci/config.json.ci
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,10 @@
"blocksPerCall": 100,
"millisecondRepeatJob": 5000,
"chunkSizeInsert": 1000,
"wrapExtensionContract": ["0xe974cc14c93fc6077b0d65f98832b846c5454a0b"]
"wrapExtensionContract": ["0xe974cc14c93fc6077b0d65f98832b846c5454a0b"],
"reindex": {
"limitRecordGet": 2000
}
},
"erc721": {
"key": "erc721",
Expand Down
5 changes: 4 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,10 @@
"blocksPerCall": 100,
"millisecondRepeatJob": 2000,
"chunkSizeInsert": 1000,
"wrapExtensionContract": ["0xe974cc14c93fc6077b0d65f98832b846c5454a0b"]
"wrapExtensionContract": ["0xe974cc14c93fc6077b0d65f98832b846c5454a0b"],
"reindex": {
"limitRecordGet": 2000
}
},
"erc721": {
"key": "erc721",
Expand Down
13 changes: 6 additions & 7 deletions src/services/evm/erc20.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,12 @@ export default class Erc20Service extends BullableService {
],
config.erc20.key
);
const erc20Activities: Erc20Activity[] =
await Erc20Handler.buildErc20Activities(
startBlock,
endBlock,
trx,
this.logger
);
const { erc20Activities } = await Erc20Handler.buildErc20Activities(
startBlock,
endBlock,
trx,
this.logger
);
await this.handleMissingErc20Contract(erc20Activities, trx);
if (erc20Activities.length > 0) {
this.logger.info(
Expand Down
31 changes: 28 additions & 3 deletions src/services/evm/erc20_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,12 @@ export class Erc20Handler {
endBlock: number,
trx: Knex.Transaction,
logger: Moleculer.LoggerInstance,
addresses?: string[]
addresses?: string[],
page?: {
prevEvmEventId?: number;
limitRecordGet: number;
prevCosmosEventId?: number;
}
) {
const erc20Activities: Erc20Activity[] = [];
const erc20Events = await EvmEvent.query()
Expand All @@ -185,6 +190,11 @@ export class Erc20Handler {
if (addresses) {
builder.whereIn('evm_event.address', addresses);
}
if (page && page.prevEvmEventId !== undefined) {
builder
.andWhere('evm_event.id', '>', page.prevEvmEventId)
.limit(page.limitRecordGet);
}
})
.where('evm_event.block_height', '>', startBlock)
.andWhere('evm_event.block_height', '<=', endBlock)
Expand Down Expand Up @@ -213,6 +223,11 @@ export class Erc20Handler {
.where('attributes.key', EventAttribute.ATTRIBUTE_KEY.ERC20_TOKEN)
.whereIn(knex.raw('lower("value")'), addresses);
}
if (page && page.prevCosmosEventId !== undefined) {
builder
.andWhere('event.id', '>', page.prevCosmosEventId)
.limit(page.limitRecordGet);
}
})
.withGraphFetched('[transaction, attributes]')
.orderBy('event.id', 'asc');
Expand Down Expand Up @@ -244,14 +259,19 @@ export class Erc20Handler {
erc20Activities.push(activity);
}
});
return _.sortBy(erc20Activities, 'cosmos_tx_id');
return {
erc20Activities: _.sortBy(erc20Activities, 'cosmos_tx_id'),
prevEvmEventId: erc20Events[erc20Events.length - 1]?.id,
prevCosmosEventId: erc20CosmosEvents[erc20CosmosEvents.length - 1]?.id,
};
}

static async getErc20Activities(
startBlock: number,
endBlock: number,
trx?: Knex.Transaction,
addresses?: string[]
addresses?: string[],
page?: { prevId: number; limitRecordGet: number }
): Promise<Erc20Activity[]> {
return Erc20Activity.query()
.modify((builder) => {
Expand All @@ -261,6 +281,11 @@ export class Erc20Handler {
if (trx) {
builder.transacting(trx);
}
if (page) {
builder
.andWhere('erc20_activity.id', '>', page.prevId)
.limit(page.limitRecordGet);
}
})
.leftJoin(
'account as from_account',
Expand Down
122 changes: 82 additions & 40 deletions src/services/evm/erc20_reindex.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-await-in-loop */
import Moleculer from 'moleculer';
import { getContract, PublicClient } from 'viem';
import config from '../../../config.json' assert { type: 'json' };
Expand Down Expand Up @@ -74,49 +75,90 @@ export class Erc20Reindexer {
})
)
.transacting(trx);
const erc20Activities = await Erc20Handler.buildErc20Activities(
0,
Number(blockHeight),
trx,
this.logger,
[address]
);
if (erc20Activities.length > 0) {
await knex
.batchInsert(
'erc20_activity',
erc20Activities,
config.erc20.chunkSizeInsert
)
.transacting(trx);
const {limitRecordGet} = config.erc20.reindex;
let prevEvmEventId = 0;
let prevCosmosEventId = '0';
let numActivities = 0;
while (true) {
const resultBuildErc20Activities =
await Erc20Handler.buildErc20Activities(
0,
Number(blockHeight),
trx,
this.logger,
[address],
{
prevEvmEventId,
limitRecordGet,
}
);
const {erc20Activities} = resultBuildErc20Activities;
if (erc20Activities.length > 0) {
const resultInsert: any = await knex
.batchInsert(
'erc20_activity',
erc20Activities,
config.erc20.chunkSizeInsert
)
.transacting(trx);
numActivities += resultInsert[0].rowCount;
}
prevEvmEventId = resultBuildErc20Activities.prevEvmEventId;
prevCosmosEventId = resultBuildErc20Activities.prevCosmosEventId;
if (prevEvmEventId === undefined && prevCosmosEventId === undefined) {
break;
}
}
const erc20ActivitiesInDb = await Erc20Handler.getErc20Activities(
0,
Number(blockHeight),
trx,
[address]
);
// get missing Account
const missingAccountsAddress = Array.from(
new Set(
[
...erc20ActivitiesInDb
.filter((e) => !e.from_account_id)
.map((e) => e.from),
...erc20ActivitiesInDb
.filter((e) => !e.to_account_id)
.map((e) => e.to),
].map((e) =>
convertEthAddressToBech32Address(config.networkPrefixAddress, e)
) as string[]
)
);
if (missingAccountsAddress.length > 0) {
throw new Error(
`Missing accounts ${missingAccountsAddress}. You should reindex them`
this.logger.info(`Reindex erc20 activities ${address} done.`);
let prevId = 0;
let numChunk = 1;
while (true) {
const erc20ActivitiesInDb = await Erc20Handler.getErc20Activities(
0,
Number(blockHeight),
trx,
[address],
{
prevId,
limitRecordGet,
}
);
// get missing Account
const missingAccountsAddress = Array.from(
new Set(
[
...erc20ActivitiesInDb
.filter((e) => !e.from_account_id)
.map((e) => e.from),
...erc20ActivitiesInDb
.filter((e) => !e.to_account_id)
.map((e) => e.to),
].map((e) =>
convertEthAddressToBech32Address(config.networkPrefixAddress, e)
) as string[]
)
);
if (missingAccountsAddress.length > 0) {
throw new Error(
`Missing accounts ${missingAccountsAddress}. You should reindex them`
);
}
if (erc20ActivitiesInDb.length > 0) {
await Erc20Handler.updateErc20AccountsBalance(
erc20ActivitiesInDb,
trx
);
prevId = erc20ActivitiesInDb[erc20ActivitiesInDb.length - 1].id;
this.logger.info(
`Reindex erc20 contract ${address}: Chunk ${numChunk}/${Math.floor(
numActivities / limitRecordGet + 1
)} done`
);
numChunk += 1;
} else {
break;
}
}
await Erc20Handler.updateErc20AccountsBalance(erc20ActivitiesInDb, trx);
});
}
}

0 comments on commit 5f1fbe8

Please sign in to comment.