diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index 299cd309b..4bb356748 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository'; import { RowDataPacket } from 'mysql2'; class DatabaseMigration { - private static currentVersion = 96; + private static currentVersion = 97; private queryTimeout = 3600_000; private statisticsAddedIndexed = false; private uniqueLogs: string[] = []; @@ -1135,6 +1135,12 @@ class DatabaseMigration { await this.$executeQuery(`ALTER TABLE blocks_audits MODIFY time timestamp NOT NULL DEFAULT 0`); await this.updateToSchemaVersion(96); } + + if (databaseSchemaVersion < 97) { + await this.$executeQuery('ALTER TABLE blocks DROP FOREIGN KEY IF EXISTS `blocks_ibfk_1`'); + await this.$executeQuery('ALTER TABLE blocks ADD FOREIGN KEY (`pool_id`) REFERENCES `pools` (`id`) ON DELETE CASCADE'); + await this.updateToSchemaVersion(97); + } } /** diff --git a/backend/src/api/pools-parser.ts b/backend/src/api/pools-parser.ts index 2895da5a5..9e9e4f22f 100644 --- a/backend/src/api/pools-parser.ts +++ b/backend/src/api/pools-parser.ts @@ -45,6 +45,12 @@ class PoolsParser { let reindexUnknown = false; let clearCache = false; + const poolsDict: { [key: string]: PoolTag } = {}; + for (const pool of this.miningPools) { + poolsDict[pool.id] = pool; + } + const dbPools = await PoolsRepository.$getPools(); + const dbPoolsDict: { [key: string]: PoolTag } = {}; for (const pool of this.miningPools) { if (!pool.id) { @@ -74,7 +80,7 @@ class PoolsParser { logger.warn(`Mining pool ${pool.name} has no 'regexes' defined.`); } - const poolDB = await PoolsRepository.$getPoolByUniqueId(pool.id, false); + const poolDB = dbPoolsDict[pool.id]; if (!poolDB) { // New mining pool const slug = pool.name.replace(/[^a-z0-9]/gi, '').toLowerCase(); @@ -108,6 +114,15 @@ class PoolsParser { } } + for (const pool of dbPools) { + if (!poolsDict[pool.id]) { + logger.notice(`Removing ${pool.name} mining pool from database.`); + await PoolsRepository.$deleteMiningPool(pool.id); + reindexUnknown = true; + clearCache = true; + } + } + if (reindexUnknown) { logger.notice(`Updating addresses and/or coinbase tags for unknown mining pool.`); let unknownPool; diff --git a/backend/src/repositories/PoolsRepository.ts b/backend/src/repositories/PoolsRepository.ts index eda792bb3..fad64934e 100644 --- a/backend/src/repositories/PoolsRepository.ts +++ b/backend/src/repositories/PoolsRepository.ts @@ -162,6 +162,35 @@ class PoolsRepository { } } + /** + * Delete a mining pool from the database + * + * @param poolId + */ + public async $deleteMiningPool(poolId: number): Promise { + try { + const unknownPool = await this.$getUnknownPool(); + if (!unknownPool) { + throw new Error('Cannot find Unknown pool'); + } + + await DB.query(` + UPDATE blocks + SET pool_id = ? + WHERE pool_id = ?`, + [unknownPool.id, poolId] + ); + + await DB.query(` + DELETE FROM pools + WHERE id = ?`, + [poolId] + ); + } catch (e: any) { + logger.err(`Cannot delete mining pool id ${poolId}. Reason: ` + (e instanceof Error ? e.message : e)); + } + } + /** * Rename an existing mining pool *