more misc JS-side gbt performance optimizations

This commit is contained in:
Mononaut 2023-06-30 14:46:44 -04:00
parent 0ddfa94b59
commit af6de9b72c
No known key found for this signature in database
GPG Key ID: A3F058E41374C04E

View File

@ -1,4 +1,4 @@
import { GbtGenerator, ThreadTransaction as RustThreadTransaction } from '../../rust-gbt'; import { GbtGenerator, GbtResult, ThreadTransaction as RustThreadTransaction } from '../../rust-gbt';
import logger from '../logger'; import logger from '../logger';
import { MempoolBlock, MempoolTransactionExtended, TransactionStripped, MempoolBlockWithTransactions, MempoolBlockDelta, Ancestor, CompactThreadTransaction, EffectiveFeeStats } from '../mempool.interfaces'; import { MempoolBlock, MempoolTransactionExtended, TransactionStripped, MempoolBlockWithTransactions, MempoolBlockDelta, Ancestor, CompactThreadTransaction, EffectiveFeeStats } from '../mempool.interfaces';
import { Common, OnlineFeeStatsCalculator } from './common'; import { Common, OnlineFeeStatsCalculator } from './common';
@ -262,7 +262,7 @@ class MempoolBlocks {
// clean up thread error listener // clean up thread error listener
this.txSelectionWorker?.removeListener('error', threadErrorListener); this.txSelectionWorker?.removeListener('error', threadErrorListener);
const processed = this.processBlockTemplates(newMempool, blocks, null, rates, clusters, saveResults); const processed = this.processBlockTemplates(newMempool, blocks, null, Object.entries(rates), Object.values(clusters), saveResults);
logger.debug(`makeBlockTemplates completed in ${(Date.now() - start)/1000} seconds`); logger.debug(`makeBlockTemplates completed in ${(Date.now() - start)/1000} seconds`);
@ -318,7 +318,7 @@ class MempoolBlocks {
// clean up thread error listener // clean up thread error listener
this.txSelectionWorker?.removeListener('error', threadErrorListener); this.txSelectionWorker?.removeListener('error', threadErrorListener);
this.processBlockTemplates(newMempool, blocks, null, rates, clusters, saveResults); this.processBlockTemplates(newMempool, blocks, null, Object.entries(rates), Object.values(clusters), saveResults);
logger.debug(`updateBlockTemplates completed in ${(Date.now() - start) / 1000} seconds`); logger.debug(`updateBlockTemplates completed in ${(Date.now() - start) / 1000} seconds`);
} catch (e) { } catch (e) {
logger.err('updateBlockTemplates failed. ' + (e instanceof Error ? e.message : e)); logger.err('updateBlockTemplates failed. ' + (e instanceof Error ? e.message : e));
@ -415,10 +415,10 @@ class MempoolBlocks {
} }
} }
private processBlockTemplates(mempool: { [txid: string]: MempoolTransactionExtended }, blocks: string[][], blockWeights: number[] | null, rates: { [root: string]: number }, clusters: { [root: string]: string[] }, saveResults): MempoolBlockWithTransactions[] { private processBlockTemplates(mempool: { [txid: string]: MempoolTransactionExtended }, blocks: string[][], blockWeights: number[] | null, rates: [string, number][], clusters: string[][], saveResults): MempoolBlockWithTransactions[] {
for (const txid of Object.keys(rates)) { for (const [txid, rate] of rates) {
if (txid in mempool) { if (txid in mempool) {
mempool[txid].effectiveFeePerVsize = rates[txid]; mempool[txid].effectiveFeePerVsize = rate;
mempool[txid].cpfpChecked = false; mempool[txid].cpfpChecked = false;
} }
} }
@ -437,7 +437,7 @@ class MempoolBlocks {
feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5, [10, 20, 30, 40, 50, 60, 70, 80, 90]); feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5, [10, 20, 30, 40, 50, 60, 70, 80, 90]);
} }
for (const cluster of Object.values(clusters)) { for (const cluster of clusters) {
for (const memberTxid of cluster) { for (const memberTxid of cluster) {
const mempoolTx = mempool[memberTxid]; const mempoolTx = mempool[memberTxid];
if (mempoolTx) { if (mempoolTx) {
@ -465,12 +465,10 @@ class MempoolBlocks {
} }
} }
const readyBlocks: { transactionIds, transactions, totalSize, totalWeight, totalFees, feeStats }[] = [];
const sizeLimit = (config.MEMPOOL.BLOCK_WEIGHT_UNITS / 4) * 1.2; const sizeLimit = (config.MEMPOOL.BLOCK_WEIGHT_UNITS / 4) * 1.2;
// update this thread's mempool with the results // update this thread's mempool with the results
for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) { let mempoolTx: MempoolTransactionExtended;
const block: string[] = blocks[blockIndex]; const mempoolBlocks: MempoolBlockWithTransactions[] = blocks.map((block, blockIndex) => {
let mempoolTx: MempoolTransactionExtended;
let totalSize = 0; let totalSize = 0;
let totalVsize = 0; let totalVsize = 0;
let totalWeight = 0; let totalWeight = 0;
@ -510,18 +508,14 @@ class MempoolBlocks {
} }
} }
} }
readyBlocks.push({ return this.dataToMempoolBlocks(
transactionIds: block, block,
transactions, transactions,
totalSize, totalSize,
totalWeight, totalWeight,
totalFees, totalFees,
feeStats: (hasBlockStack && blockIndex === lastBlockIndex && feeStatsCalculator) ? feeStatsCalculator.getRawFeeStats() : undefined, (hasBlockStack && blockIndex === lastBlockIndex && feeStatsCalculator) ? feeStatsCalculator.getRawFeeStats() : undefined,
}); );
}
const mempoolBlocks = readyBlocks.map((b) => {
return this.dataToMempoolBlocks(b.transactionIds, b.transactions, b.totalSize, b.totalWeight, b.totalFees, b.feeStats);
}); });
if (saveResults) { if (saveResults) {
@ -603,16 +597,8 @@ class MempoolBlocks {
return { blocks: convertedBlocks, rates: convertedRates, clusters: convertedClusters } as { blocks: string[][], rates: { [root: string]: number }, clusters: { [root: string]: string[] }}; return { blocks: convertedBlocks, rates: convertedRates, clusters: convertedClusters } as { blocks: string[][], rates: { [root: string]: number }, clusters: { [root: string]: string[] }};
} }
private convertNapiResultTxids({ blocks, blockWeights, rates, clusters }: { blocks: number[][], blockWeights: number[], rates: number[][], clusters: number[][]}) private convertNapiResultTxids({ blocks, blockWeights, rates, clusters }: GbtResult)
: { blocks: string[][], blockWeights: number[], rates: { [root: string]: number }, clusters: { [root: string]: string[] }} { : { blocks: string[][], blockWeights: number[], rates: [string, number][], clusters: string[][] } {
const rateMap = new Map<number, number>();
const clusterMap = new Map<number, number[]>();
for (const rate of rates) {
rateMap.set(rate[0], rate[1]);
}
for (const cluster of clusters) {
clusterMap.set(cluster[0], cluster);
}
const convertedBlocks: string[][] = blocks.map(block => block.map(uid => { const convertedBlocks: string[][] = blocks.map(block => block.map(uid => {
const txid = this.uidMap.get(uid); const txid = this.uidMap.get(uid);
if (txid !== undefined) { if (txid !== undefined) {
@ -621,28 +607,16 @@ class MempoolBlocks {
throw new Error('GBT returned a block containing a transaction with unknown uid'); throw new Error('GBT returned a block containing a transaction with unknown uid');
} }
})); }));
const convertedRates = {}; const convertedRates: [string, number][] = [];
for (const rateUid of rateMap.keys()) { for (const [rateUid, rate] of rates) {
const rateTxid = this.uidMap.get(rateUid); const rateTxid = this.uidMap.get(rateUid) as string;
if (rateTxid !== undefined) { convertedRates.push([rateTxid, rate]);
convertedRates[rateTxid] = rateMap.get(rateUid);
} else {
throw new Error('GBT returned a fee rate for a transaction with unknown uid');
}
} }
const convertedClusters = {}; const convertedClusters: string[][] = [];
for (const rootUid of clusterMap.keys()) { for (const cluster of clusters) {
const rootTxid = this.uidMap.get(rootUid); convertedClusters.push(cluster.map(uid => this.uidMap.get(uid)) as string[]);
if (rootTxid !== undefined) {
const members = clusterMap.get(rootUid)?.map(uid => {
return this.uidMap.get(uid);
});
convertedClusters[rootTxid] = members;
} else {
throw new Error('GBT returned a cluster rooted in a transaction with unknown uid');
}
} }
return { blocks: convertedBlocks, blockWeights, rates: convertedRates, clusters: convertedClusters } as { blocks: string[][], blockWeights: number[], rates: { [root: string]: number }, clusters: { [root: string]: string[] }}; return { blocks: convertedBlocks, blockWeights, rates: convertedRates, clusters: convertedClusters };
} }
} }