diff --git a/src/utils/offchainState.ts b/src/utils/offchainState.ts index d01b43841..875ec1734 100644 --- a/src/utils/offchainState.ts +++ b/src/utils/offchainState.ts @@ -5,6 +5,7 @@ import { createLogger } from '@subsquid/logger' import assert from 'assert' import { uniqueId } from './crypto' import { defaultNotificationPreferences } from './notification/helpers' +import { NextEntityId } from '../model' const DEFAULT_EXPORT_PATH = path.resolve(__dirname, '../../db/export/export.json') @@ -90,6 +91,11 @@ export class OffchainState { private logger = createLogger('offchainState') private _isImported = false + private globalCountersMigration = { + // destination version : [global counters names] + '3.1.0': ['Account'], + } + private migrations: Migrations = { '3.1.0': migrateExportDataToV310, '3.0.0': migrateExportDataToV300, @@ -159,7 +165,7 @@ export class OffchainState { public prepareExportData(exportState: ExportedState, em: EntityManager): ExportedData { let { data } = exportState Object.entries(this.migrations) - .sort(([a], [b]) => this.versionToNumber(a) - this.versionToNumber(b)) + .sort(([a], [b]) => this.versionToNumber(a) - this.versionToNumber(b)) // sort in increasing order .forEach(([version, fn]) => { if (this.versionToNumber(exportState.orionVersion || '0') < this.versionToNumber(version)) { this.logger.info(`Migrating export data to version ${version}`) @@ -175,7 +181,8 @@ export class OffchainState { `Cannot perform offchain data import! Export file ${exportFilePath} does not exist!` ) } - const data = this.prepareExportData(JSON.parse(fs.readFileSync(exportFilePath, 'utf-8')), em) + const exportFile = JSON.parse(fs.readFileSync(exportFilePath, 'utf-8')) + const data = this.prepareExportData(exportFile, em) this.logger.info('Importing offchain state') for (const [entityName, { type, values }] of Object.entries(data)) { if (!values.length) { @@ -244,6 +251,11 @@ export class OffchainState { `Done ${type === 'update' ? 'updating' : 'inserting'} ${entityName} entities` ) } + + // migrate counters for NextEntityId + const { version } = exportFile + await this.migrateCounters(version, em) + const renamedExportFilePath = `${exportFilePath}.imported` this.logger.info(`Renaming export file to ${renamedExportFilePath})...`) fs.renameSync(exportFilePath, renamedExportFilePath) @@ -261,4 +273,19 @@ export class OffchainState { this.logger.info(`Last export block number established: ${blockNumber}`) return blockNumber } + + private async migrateCounters(exportedVersion: string, em: EntityManager): Promise { + Object.entries(this.globalCountersMigration) + .sort(([a], [b]) => this.versionToNumber(a) - this.versionToNumber(b)) // sort in increasing order + .forEach(([version, counters]) => { + if (this.versionToNumber(exportedVersion) < this.versionToNumber(version)) { + this.logger.info(`Migrating global counters to version ${version}`) + counters.forEach(async (entityName) => { + // build query that gets the entityName with the highest id + const latestId = await em.query(`SELECT id FROM ${entityName} ORDER BY id DESC LIMIT 1`) + await em.save(new NextEntityId({ entityName, nextId: Number(latestId) + 1 })) + }) + } + }) + } }