diff --git a/backend/src/api/bitcoin/bitcoin-api.ts b/backend/src/api/bitcoin/bitcoin-api.ts index 307736737..a0cc41770 100644 --- a/backend/src/api/bitcoin/bitcoin-api.ts +++ b/backend/src/api/bitcoin/bitcoin-api.ts @@ -29,6 +29,7 @@ class BitcoinApi implements AbstractBitcoinApi { weight: block.weight, previousblockhash: block.previousblockhash, mediantime: block.mediantime, + stale: block.confirmations === -1, }; } diff --git a/backend/src/api/bitcoin/esplora-api.interface.ts b/backend/src/api/bitcoin/esplora-api.interface.ts index 6d50bddfd..5b86952b0 100644 --- a/backend/src/api/bitcoin/esplora-api.interface.ts +++ b/backend/src/api/bitcoin/esplora-api.interface.ts @@ -89,6 +89,7 @@ export namespace IEsploraApi { weight: number; previousblockhash: string; mediantime: number; + stale: boolean; } export interface Address { diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 16335c36a..4d218ed54 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -656,10 +656,6 @@ class Blocks { const blockSummary: BlockSummary = this.summarizeBlockTransactions(block.id, cpfpSummary.transactions); this.updateTimerProgress(timer, `got block data for ${this.currentBlockHeight}`); - // start async callbacks - this.updateTimerProgress(timer, `starting async callbacks for ${this.currentBlockHeight}`); - const callbackPromises = this.newAsyncBlockCallbacks.map((cb) => cb(blockExtended, txIds, transactions)); - if (Common.indexingEnabled()) { if (!fastForwarded) { const lastBlock = await blocksRepository.$getBlockByHeight(blockExtended.height - 1); @@ -671,9 +667,11 @@ class Blocks { await BlocksRepository.$deleteBlocksFrom(lastBlock.height - 10); await HashratesRepository.$deleteLastEntries(); await cpfpRepository.$deleteClustersFrom(lastBlock.height - 10); + this.blocks = this.blocks.slice(0, -10); this.updateTimerProgress(timer, `rolled back chain divergence from ${this.currentBlockHeight}`); for (let i = 10; i >= 0; --i) { const newBlock = await this.$indexBlock(lastBlock.height - i); + this.blocks.push(newBlock); this.updateTimerProgress(timer, `reindexed block`); let cpfpSummary; if (config.MEMPOOL.CPFP_INDEXING) { @@ -722,6 +720,10 @@ class Blocks { } } + // start async callbacks + this.updateTimerProgress(timer, `starting async callbacks for ${this.currentBlockHeight}`); + const callbackPromises = this.newAsyncBlockCallbacks.map((cb) => cb(blockExtended, txIds, transactions)); + if (block.height % 2016 === 0) { if (Common.indexingEnabled()) { await DifficultyAdjustmentsRepository.$saveAdjustments({ @@ -814,6 +816,16 @@ class Blocks { return blockExtended; } + public async $indexStaleBlock(hash: string): Promise { + const block: IEsploraApi.Block = await bitcoinCoreApi.$getBlock(hash); + const transactions = await this.$getTransactionsExtended(hash, block.height, true); + const blockExtended = await this.$getBlockExtended(block, transactions); + + blockExtended.canonical = await bitcoinApi.$getBlockHash(block.height); + + return blockExtended; + } + /** * Get one block by its hash */ @@ -831,7 +843,11 @@ class Blocks { // Bitcoin network, add our custom data on top const block: IEsploraApi.Block = await bitcoinCoreApi.$getBlock(hash); - return await this.$indexBlock(block.height); + if (block.stale) { + return await this.$indexStaleBlock(hash); + } else { + return await this.$indexBlock(block.height); + } } public async $getStrippedBlockTransactions(hash: string, skipMemoryCache = false, diff --git a/backend/src/repositories/BlocksAuditsRepository.ts b/backend/src/repositories/BlocksAuditsRepository.ts index 8ad035f32..31107db75 100644 --- a/backend/src/repositories/BlocksAuditsRepository.ts +++ b/backend/src/repositories/BlocksAuditsRepository.ts @@ -62,8 +62,7 @@ class BlocksAuditRepositories { public async $getBlockAudit(hash: string): Promise { try { const [rows]: any[] = await DB.query( - `SELECT blocks.height, blocks.hash as id, UNIX_TIMESTAMP(blocks.blockTimestamp) as timestamp, blocks.size, - blocks.weight, blocks.tx_count, + `SELECT blocks_audits.height, blocks_audits.hash as id, UNIX_TIMESTAMP(blocks_audits.time) as timestamp, template, missing_txs as missingTxs, added_txs as addedTxs, @@ -73,7 +72,6 @@ class BlocksAuditRepositories { expected_fees as expectedFees, expected_weight as expectedWeight FROM blocks_audits - JOIN blocks ON blocks.hash = blocks_audits.hash JOIN blocks_templates ON blocks_templates.id = blocks_audits.hash WHERE blocks_audits.hash = "${hash}" `); diff --git a/frontend/src/app/interfaces/electrs.interface.ts b/frontend/src/app/interfaces/electrs.interface.ts index dcccfb67c..4cb6b41db 100644 --- a/frontend/src/app/interfaces/electrs.interface.ts +++ b/frontend/src/app/interfaces/electrs.interface.ts @@ -120,6 +120,7 @@ export interface Block { size: number; weight: number; previousblockhash: string; + stale?: boolean; } export interface Address {