diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 12203068f..b6b5974a7 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -158,6 +158,13 @@ class Blocks { }; } + public summarizeBlockTransactions(hash: string, transactions: TransactionExtended[]): BlockSummary { + return { + id: hash, + transactions: Common.stripTransactions(transactions), + }; + } + private convertLiquidFees(block: IBitcoinApi.VerboseBlock): IBitcoinApi.VerboseBlock { block.tx.forEach(tx => { tx.fee = Object.values(tx.fee || {}).reduce((total, output) => total + output, 0); @@ -646,7 +653,7 @@ class Blocks { } const cpfpSummary: CpfpSummary = Common.calculateCpfp(block.height, transactions); const blockExtended: BlockExtended = await this.$getBlockExtended(block, cpfpSummary.transactions); - const blockSummary: BlockSummary = this.summarizeBlock(verboseBlock); + const blockSummary: BlockSummary = this.summarizeBlockTransactions(block.id, cpfpSummary.transactions); this.updateTimerProgress(timer, `got block data for ${this.currentBlockHeight}`); // start async callbacks @@ -668,12 +675,13 @@ class Blocks { for (let i = 10; i >= 0; --i) { const newBlock = await this.$indexBlock(lastBlock.height - i); this.updateTimerProgress(timer, `reindexed block`); - await this.$getStrippedBlockTransactions(newBlock.id, true, true); - this.updateTimerProgress(timer, `reindexed block summary`); + let cpfpSummary; if (config.MEMPOOL.CPFP_INDEXING) { - await this.$indexCPFP(newBlock.id, lastBlock.height - i); + cpfpSummary = await this.$indexCPFP(newBlock.id, lastBlock.height - i); this.updateTimerProgress(timer, `reindexed block cpfp`); } + await this.$getStrippedBlockTransactions(newBlock.id, true, true, cpfpSummary, newBlock.height); + this.updateTimerProgress(timer, `reindexed block summary`); } await mining.$indexDifficultyAdjustments(); await DifficultyAdjustmentsRepository.$deleteLastAdjustment(); @@ -704,7 +712,7 @@ class Blocks { // Save blocks summary for visualization if it's enabled if (Common.blocksSummariesIndexingEnabled() === true) { - await this.$getStrippedBlockTransactions(blockExtended.id, true); + await this.$getStrippedBlockTransactions(blockExtended.id, true, false, cpfpSummary, blockExtended.height); this.updateTimerProgress(timer, `saved block summary for ${this.currentBlockHeight}`); } if (config.MEMPOOL.CPFP_INDEXING) { @@ -827,7 +835,7 @@ class Blocks { } public async $getStrippedBlockTransactions(hash: string, skipMemoryCache = false, - skipDBLookup = false): Promise + skipDBLookup = false, cpfpSummary?: CpfpSummary, blockHeight?: number): Promise { if (skipMemoryCache === false) { // Check the memory cache @@ -845,13 +853,35 @@ class Blocks { } } - // Call Core RPC - const block = await bitcoinClient.getBlock(hash, 2); - const summary = this.summarizeBlock(block); + let height = blockHeight; + let summary: BlockSummary; + if (cpfpSummary) { + summary = { + id: hash, + transactions: cpfpSummary.transactions.map(tx => { + return { + txid: tx.txid, + fee: tx.fee, + vsize: tx.vsize, + value: Math.round(tx.vout.reduce((acc, vout) => acc + (vout.value ? vout.value : 0), 0)), + rate: tx.effectiveFeePerVsize + }; + }), + }; + } else { + // Call Core RPC + const block = await bitcoinClient.getBlock(hash, 2); + summary = this.summarizeBlock(block); + height = block.height; + } + if (height == null) { + const block = await bitcoinApi.$getBlock(hash); + height = block.height; + } // Index the response if needed if (Common.blocksSummariesIndexingEnabled() === true) { - await BlocksSummariesRepository.$saveTransactions(block.height, block.hash, summary.transactions); + await BlocksSummariesRepository.$saveTransactions(height, hash, summary.transactions); } return summary.transactions; diff --git a/backend/src/api/common.ts b/backend/src/api/common.ts index 234535cc4..9836559ae 100644 --- a/backend/src/api/common.ts +++ b/backend/src/api/common.ts @@ -113,6 +113,10 @@ export class Common { }; } + static stripTransactions(txs: TransactionExtended[]): TransactionStripped[] { + return txs.map(this.stripTransaction); + } + static sleep$(ms: number): Promise { return new Promise((resolve) => { setTimeout(() => { diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts index 8aaab5ab5..a4ce970dd 100644 --- a/backend/src/api/websocket-handler.ts +++ b/backend/src/api/websocket-handler.ts @@ -562,14 +562,7 @@ class WebsocketHandler { const { censored, added, fresh, sigop, score, similarity } = Audit.auditBlock(transactions, projectedBlocks, auditMempool); const matchRate = Math.round(score * 100 * 100) / 100; - const stripped = projectedBlocks[0]?.transactions ? projectedBlocks[0].transactions.map((tx) => { - return { - txid: tx.txid, - vsize: tx.vsize, - fee: tx.fee ? Math.round(tx.fee) : 0, - value: tx.value, - }; - }) : []; + const stripped = projectedBlocks[0]?.transactions ? projectedBlocks[0].transactions : []; let totalFees = 0; let totalWeight = 0;