diff --git a/backend/rust-gbt/index.d.ts b/backend/rust-gbt/index.d.ts index 2bd8a620a..d1cb85b92 100644 --- a/backend/rust-gbt/index.d.ts +++ b/backend/rust-gbt/index.d.ts @@ -45,5 +45,6 @@ export class GbtResult { blockWeights: Array clusters: Array> rates: Array> - constructor(blocks: Array>, blockWeights: Array, clusters: Array>, rates: Array>) + overflow: Array + constructor(blocks: Array>, blockWeights: Array, clusters: Array>, rates: Array>, overflow: Array) } diff --git a/backend/rust-gbt/src/gbt.rs b/backend/rust-gbt/src/gbt.rs index e1ceeefb6..38bf826a6 100644 --- a/backend/rust-gbt/src/gbt.rs +++ b/backend/rust-gbt/src/gbt.rs @@ -271,6 +271,7 @@ pub fn gbt(mempool: &mut ThreadTransactionsMap, accelerations: &[ThreadAccelerat block_weights, clusters, rates, + overflow, } } diff --git a/backend/rust-gbt/src/lib.rs b/backend/rust-gbt/src/lib.rs index 53db0ba21..edc9714ee 100644 --- a/backend/rust-gbt/src/lib.rs +++ b/backend/rust-gbt/src/lib.rs @@ -133,6 +133,7 @@ pub struct GbtResult { pub block_weights: Vec, pub clusters: Vec>, pub rates: Vec>, // Tuples not supported. u32 fits inside f64 + pub overflow: Vec, } /// All on another thread, this runs an arbitrary task in between diff --git a/backend/src/api/mempool-blocks.ts b/backend/src/api/mempool-blocks.ts index 2097acd4b..0ca550f4c 100644 --- a/backend/src/api/mempool-blocks.ts +++ b/backend/src/api/mempool-blocks.ts @@ -368,12 +368,15 @@ class MempoolBlocks { // run the block construction algorithm in a separate thread, and wait for a result const rustGbt = saveResults ? this.rustGbtGenerator : new GbtGenerator(); try { - const { blocks, blockWeights, rates, clusters } = this.convertNapiResultTxids( + const { blocks, blockWeights, rates, clusters, overflow } = this.convertNapiResultTxids( await rustGbt.make(Object.values(newMempool) as RustThreadTransaction[], convertedAccelerations as RustThreadAcceleration[], this.nextUid), ); if (saveResults) { this.rustInitialized = true; } + const mempoolSize = Object.keys(newMempool).length; + const resultMempoolSize = blocks.reduce((total, block) => total + block.length, 0) + overflow.length; + logger.debug(`RUST updateBlockTemplates returned ${resultMempoolSize} txs out of ${mempoolSize} in the mempool, ${overflow.length} were unmineable`); const processed = this.processBlockTemplates(newMempool, blocks, blockWeights, rates, clusters, accelerations, accelerationPool, saveResults); logger.debug(`RUST makeBlockTemplates completed in ${(Date.now() - start)/1000} seconds`); return processed; @@ -424,7 +427,7 @@ class MempoolBlocks { // run the block construction algorithm in a separate thread, and wait for a result try { - const { blocks, blockWeights, rates, clusters } = this.convertNapiResultTxids( + const { blocks, blockWeights, rates, clusters, overflow } = this.convertNapiResultTxids( await this.rustGbtGenerator.update( added as RustThreadTransaction[], removedUids, @@ -432,16 +435,16 @@ class MempoolBlocks { this.nextUid, ), ); - //// different number of transactions is now expected, if any were unmineable - // const resultMempoolSize = blocks.reduce((total, block) => total + block.length, 0); - // if (mempoolSize !== resultMempoolSize) { - // throw new Error('GBT returned wrong number of transactions, cache is probably out of sync'); - // } else { + const resultMempoolSize = blocks.reduce((total, block) => total + block.length, 0) + overflow.length; + logger.debug(`RUST updateBlockTemplates returned ${resultMempoolSize} txs out of ${mempoolSize} in the mempool, ${overflow.length} were unmineable`); + if (mempoolSize !== resultMempoolSize) { + throw new Error('GBT returned wrong number of transactions , cache is probably out of sync'); + } else { const processed = this.processBlockTemplates(newMempool, blocks, blockWeights, rates, clusters, accelerations, accelerationPool, true); this.removeUids(removedUids); logger.debug(`RUST updateBlockTemplates completed in ${(Date.now() - start)/1000} seconds`); return processed; - // } + } } catch (e) { logger.err('RUST updateBlockTemplates failed. ' + (e instanceof Error ? e.message : e)); this.resetRustGbt(); @@ -659,8 +662,8 @@ class MempoolBlocks { return { blocks: convertedBlocks, rates: convertedRates, clusters: convertedClusters } as { blocks: string[][], rates: { [root: string]: number }, clusters: { [root: string]: string[] }}; } - private convertNapiResultTxids({ blocks, blockWeights, rates, clusters }: GbtResult) - : { blocks: string[][], blockWeights: number[], rates: [string, number][], clusters: string[][] } { + private convertNapiResultTxids({ blocks, blockWeights, rates, clusters, overflow }: GbtResult) + : { blocks: string[][], blockWeights: number[], rates: [string, number][], clusters: string[][], overflow: string[] } { const convertedBlocks: string[][] = blocks.map(block => block.map(uid => { const txid = this.uidMap.get(uid); if (txid !== undefined) { @@ -678,7 +681,15 @@ class MempoolBlocks { for (const cluster of clusters) { convertedClusters.push(cluster.map(uid => this.uidMap.get(uid)) as string[]); } - return { blocks: convertedBlocks, blockWeights, rates: convertedRates, clusters: convertedClusters }; + const convertedOverflow: string[] = overflow.map(uid => { + const txid = this.uidMap.get(uid); + if (txid !== undefined) { + return txid; + } else { + throw new Error('GBT returned an unmineable transaction with unknown uid'); + } + }); + return { blocks: convertedBlocks, blockWeights, rates: convertedRates, clusters: convertedClusters, overflow: convertedOverflow }; } }