From ac997f3d9e8456548f58b4b29bd253da3a2c8b9d Mon Sep 17 00:00:00 2001 From: nymkappa <1612910616@pm.me> Date: Fri, 29 Nov 2024 17:13:28 +0100 Subject: [PATCH] [blocks] add 2 endpoints to retreive pools-v2.json hashes --- backend/src/api/bitcoin/bitcoin.routes.ts | 31 +++++++++++++++++++++++ backend/src/api/blocks.ts | 15 ++++++++++- backend/src/api/database-migration.ts | 1 + backend/src/mempool.interfaces.ts | 2 ++ backend/src/tasks/pools-updater.ts | 2 +- 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/backend/src/api/bitcoin/bitcoin.routes.ts b/backend/src/api/bitcoin/bitcoin.routes.ts index d2d298e09..c95d89d0f 100644 --- a/backend/src/api/bitcoin/bitcoin.routes.ts +++ b/backend/src/api/bitcoin/bitcoin.routes.ts @@ -21,6 +21,7 @@ import transactionRepository from '../../repositories/TransactionRepository'; import rbfCache from '../rbf-cache'; import { calculateMempoolTxCpfp } from '../cpfp'; import { handleError } from '../../utils/api'; +import poolsUpdater from '../../tasks/pools-updater'; class BitcoinRoutes { public initRoutes(app: Application) { @@ -46,6 +47,8 @@ class BitcoinRoutes { .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/audit-summary', this.getBlockAuditSummary) .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/tx/:txid/audit', this.$getBlockTxAuditSummary) .get(config.MEMPOOL.API_URL_PREFIX + 'blocks/tip/height', this.getBlockTipHeight) + .get(config.MEMPOOL.API_URL_PREFIX + 'blocks/definition/list', this.getBlockDefinitionHashes) + .get(config.MEMPOOL.API_URL_PREFIX + 'blocks/definition/current', this.getCurrentBlockDefinitionHash) .post(config.MEMPOOL.API_URL_PREFIX + 'psbt/addparents', this.postPsbtCompletion) .get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from', this.getBlocksByBulk.bind(this)) .get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from/:to', this.getBlocksByBulk.bind(this)) @@ -657,6 +660,34 @@ class BitcoinRoutes { } } + private async getBlockDefinitionHashes(req: Request, res: Response) { + try { + const result = await blocks.$getBlockDefinitionHashes(); + if (!result) { + handleError(req, res, 503, `Service Temporarily Unavailable`); + return; + } + res.setHeader('content-type', 'application/json'); + res.send(result); + } catch (e) { + handleError(req, res, 500, e instanceof Error ? e.message : e); + } + } + + private async getCurrentBlockDefinitionHash(req: Request, res: Response) { + try { + const currentSha = await poolsUpdater.getShaFromDb(); + if (!currentSha) { + handleError(req, res, 503, `Service Temporarily Unavailable`); + return; + } + res.setHeader('content-type', 'text/plain'); + res.send(currentSha); + } catch (e) { + handleError(req, res, 500, e instanceof Error ? e.message : e); + } + } + private getBlockTipHeight(req: Request, res: Response) { try { const result = blocks.getCurrentBlockHeight(); diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index e621056ab..2b468a8f8 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -33,8 +33,8 @@ import AccelerationRepository from '../repositories/AccelerationRepository'; import { calculateFastBlockCpfp, calculateGoodBlockCpfp } from './cpfp'; import mempool from './mempool'; import CpfpRepository from '../repositories/CpfpRepository'; -import accelerationApi from './services/acceleration'; import { parseDATUMTemplateCreator } from '../utils/bitcoin-script'; +import database from '../database'; class Blocks { private blocks: BlockExtended[] = []; @@ -1462,6 +1462,19 @@ class Blocks { // not a fatal error, we'll try again next time the indexer runs } } + + public async $getBlockDefinitionHashes(): Promise { + try { + const [rows]: any = await database.query(`SELECT DISTINCT(definition_hash) FROM blocks`); + if (rows && rows.length) { + return rows.map(r => r.definition_hash); + } + } catch (e) { + // we just return an empty array + } + logger.debug(`Unable to retreive list of blocks.definition_hash from db`); + return []; + } } export default new Blocks(); diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index b9d8530bb..47fd696e4 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -779,6 +779,7 @@ class DatabaseMigration { // blocks pools-v2.json hash if (databaseSchemaVersion < 92) { await this.$executeQuery('ALTER TABLE `blocks` ADD definition_hash varchar(255) NOT NULL DEFAULT "5f32a67401929169f225f5db43c9efa795d1b159"'); + await this.$executeQuery('ALTER TABLE `blocks` ADD INDEX `definition_hash` (`definition_hash`)'); await this.updateToSchemaVersion(92); } } diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index dc703af21..e1da4be6f 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -325,6 +325,8 @@ export interface BlockExtension { // Requires coinstatsindex, will be set to NULL otherwise utxoSetSize: number | null; totalInputAmt: number | null; + // pools-v2.json git hash + definitionHash: string | undefined; } /** diff --git a/backend/src/tasks/pools-updater.ts b/backend/src/tasks/pools-updater.ts index 652383a2a..502e3613f 100644 --- a/backend/src/tasks/pools-updater.ts +++ b/backend/src/tasks/pools-updater.ts @@ -121,7 +121,7 @@ class PoolsUpdater { /** * Fetch our latest pools-v2.json sha from the db */ - private async getShaFromDb(): Promise { + public async getShaFromDb(): Promise { try { const [rows]: any[] = await DB.query('SELECT string FROM state WHERE name="pools_json_sha"'); return (rows.length > 0 ? rows[0].string : null);