diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 09ed0bebf..16335c36a 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -34,7 +34,7 @@ class Blocks { private lastDifficultyAdjustmentTime = 0; private previousDifficultyRetarget = 0; private newBlockCallbacks: ((block: BlockExtended, txIds: string[], transactions: TransactionExtended[]) => void)[] = []; - private newAsyncBlockCallbacks: ((block: BlockExtended, txIds: string[], transactions: TransactionExtended[]) => Promise)[] = []; + private newAsyncBlockCallbacks: ((block: BlockExtended, txIds: string[], transactions: MempoolTransactionExtended[]) => Promise)[] = []; private mainLoopTimeout: number = 120000; @@ -60,7 +60,7 @@ class Blocks { this.newBlockCallbacks.push(fn); } - public setNewAsyncBlockCallback(fn: (block: BlockExtended, txIds: string[], transactions: TransactionExtended[]) => Promise) { + public setNewAsyncBlockCallback(fn: (block: BlockExtended, txIds: string[], transactions: MempoolTransactionExtended[]) => Promise) { this.newAsyncBlockCallbacks.push(fn); } @@ -642,7 +642,7 @@ class Blocks { const verboseBlock = await bitcoinClient.getBlock(blockHash, 2); const block = BitcoinApi.convertBlock(verboseBlock); const txIds: string[] = await bitcoinApi.$getTxIdsForBlock(blockHash); - const transactions = await this.$getTransactionsExtended(blockHash, block.height, false, false, true); + const transactions = await this.$getTransactionsExtended(blockHash, block.height, false, false, true) as MempoolTransactionExtended[]; if (config.MEMPOOL.BACKEND !== 'esplora') { // fill in missing transaction fee data from verboseBlock for (let i = 0; i < transactions.length; i++) { diff --git a/backend/src/api/disk-cache.ts b/backend/src/api/disk-cache.ts index 17d75d07b..1e428d8b6 100644 --- a/backend/src/api/disk-cache.ts +++ b/backend/src/api/disk-cache.ts @@ -195,6 +195,7 @@ class DiskCache { if (data.mempoolArray) { for (const tx of data.mempoolArray) { + delete tx.uid; data.mempool[tx.txid] = tx; } } @@ -207,6 +208,7 @@ class DiskCache { const cacheData2 = JSON.parse(fs.readFileSync(fileName, 'utf8')); if (cacheData2.mempoolArray) { for (const tx of cacheData2.mempoolArray) { + delete tx.uid; data.mempool[tx.txid] = tx; } } else { diff --git a/backend/src/api/mempool-blocks.ts b/backend/src/api/mempool-blocks.ts index e0362b6ce..c753d2293 100644 --- a/backend/src/api/mempool-blocks.ts +++ b/backend/src/api/mempool-blocks.ts @@ -327,13 +327,21 @@ class MempoolBlocks { } } - public async $rustMakeBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, saveResults: boolean = false): Promise { + private resetRustGbt(): void { + this.rustInitialized = false; + this.rustGbtGenerator = new GbtGenerator(); + } + + private async $rustMakeBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, saveResults: boolean = false): Promise { const start = Date.now(); // reset mempool short ids - this.resetUids(); + if (saveResults) { + this.resetUids(); + } + // set missing short ids for (const tx of Object.values(newMempool)) { - this.setUid(tx); + this.setUid(tx, !saveResults); } // serialize relevant mempool data into an ArrayBuffer @@ -341,25 +349,34 @@ class MempoolBlocks { const mempoolBuffer = this.mempoolToArrayBuffer(Object.values(newMempool), newMempool); // run the block construction algorithm in a separate thread, and wait for a result + const rustGbt = saveResults ? this.rustGbtGenerator : new GbtGenerator(); try { const { blocks, rates, clusters } = this.convertNapiResultTxids( - await this.rustGbtGenerator.make(new Uint8Array(mempoolBuffer)), + await rustGbt.make(new Uint8Array(mempoolBuffer)), ); - this.rustInitialized = true; + if (saveResults) { + this.rustInitialized = true; + } const processed = this.processBlockTemplates(newMempool, blocks, rates, clusters, saveResults); logger.debug(`RUST makeBlockTemplates completed in ${(Date.now() - start)/1000} seconds`); return processed; } catch (e) { - this.rustInitialized = false; logger.err('RUST makeBlockTemplates failed. ' + (e instanceof Error ? e.message : e)); + if (saveResults) { + this.resetRustGbt(); + } } return this.mempoolBlocks; } - public async $rustUpdateBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, added: MempoolTransactionExtended[], removed: MempoolTransactionExtended[], saveResults: boolean = false): Promise { + public async $oneOffRustBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }): Promise { + return this.$rustMakeBlockTemplates(newMempool, false); + } + + public async $rustUpdateBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, added: MempoolTransactionExtended[], removed: MempoolTransactionExtended[]): Promise { if (!this.rustInitialized) { // need to reset the worker - await this.$rustMakeBlockTemplates(newMempool, saveResults); + await this.$rustMakeBlockTemplates(newMempool, true); return; } @@ -382,11 +399,11 @@ class MempoolBlocks { new Uint8Array(removedBuffer), ), ); - this.processBlockTemplates(newMempool, blocks, rates, clusters, saveResults); + this.processBlockTemplates(newMempool, blocks, rates, clusters, true); logger.debug(`RUST updateBlockTemplates completed in ${(Date.now() - start)/1000} seconds`); } catch (e) { - this.rustInitialized = false; logger.err('RUST updateBlockTemplates failed. ' + (e instanceof Error ? e.message : e)); + this.resetRustGbt(); } } diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts index 1bc594a83..00d5a6026 100644 --- a/backend/src/api/websocket-handler.ts +++ b/backend/src/api/websocket-handler.ts @@ -343,7 +343,7 @@ class WebsocketHandler { if (config.MEMPOOL.ADVANCED_GBT_MEMPOOL) { if (config.MEMPOOL.RUST_GBT) { - await mempoolBlocks.$rustUpdateBlockTemplates(newMempool, newTransactions, deletedTransactions, true); + await mempoolBlocks.$rustUpdateBlockTemplates(newMempool, newTransactions, deletedTransactions); } else { await mempoolBlocks.$updateBlockTemplates(newMempool, newTransactions, deletedTransactions, true); } @@ -574,7 +574,7 @@ class WebsocketHandler { }); } - async handleNewBlock(block: BlockExtended, txIds: string[], transactions: TransactionExtended[]): Promise { + async handleNewBlock(block: BlockExtended, txIds: string[], transactions: MempoolTransactionExtended[]): Promise { if (!this.wss) { throw new Error('WebSocket.Server is not set'); } @@ -593,7 +593,7 @@ class WebsocketHandler { auditMempool = deepClone(_memPool); if (config.MEMPOOL.ADVANCED_GBT_AUDIT) { if (config.MEMPOOL.RUST_GBT) { - projectedBlocks = await mempoolBlocks.$rustMakeBlockTemplates(auditMempool, false); + projectedBlocks = await mempoolBlocks.$oneOffRustBlockTemplates(auditMempool); } else { projectedBlocks = await mempoolBlocks.$makeBlockTemplates(auditMempool, false); } @@ -664,7 +664,7 @@ class WebsocketHandler { if (config.MEMPOOL.ADVANCED_GBT_MEMPOOL) { if (config.MEMPOOL.RUST_GBT) { - await mempoolBlocks.$rustMakeBlockTemplates(_memPool, true); + await mempoolBlocks.$rustUpdateBlockTemplates(_memPool, [], transactions); } else { await mempoolBlocks.$makeBlockTemplates(_memPool, true); }