misc JS-side gbt performance optimizations
This commit is contained in:
		
							parent
							
								
									1e1bf14692
								
							
						
					
					
						commit
						fe84d6e1ab
					
				@ -371,7 +371,7 @@ class MempoolBlocks {
 | 
			
		||||
    return this.$rustMakeBlockTemplates(newMempool, false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async $rustUpdateBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, added: MempoolTransactionExtended[], removed: MempoolTransactionExtended[]): Promise<void> {
 | 
			
		||||
  public async $rustUpdateBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, mempoolSize: number, added: MempoolTransactionExtended[], removed: MempoolTransactionExtended[]): Promise<void> {
 | 
			
		||||
    // sanity check to avoid approaching uint32 uid overflow
 | 
			
		||||
    if (this.nextUid + added.length > MAX_UINT32) {
 | 
			
		||||
      this.resetRustGbt();
 | 
			
		||||
@ -401,13 +401,13 @@ class MempoolBlocks {
 | 
			
		||||
          removedUids,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
      const expectedMempoolSize = Object.keys(newMempool).length;
 | 
			
		||||
      const actualMempoolSize = blocks.reduce((total, block) => total + block.length, 0);
 | 
			
		||||
      if (expectedMempoolSize !== actualMempoolSize) {
 | 
			
		||||
      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 {
 | 
			
		||||
        this.processBlockTemplates(newMempool, blocks, blockWeights, rates, clusters, true);
 | 
			
		||||
      }
 | 
			
		||||
      this.removeUids(removedUids);
 | 
			
		||||
      logger.debug(`RUST updateBlockTemplates completed in ${(Date.now() - start)/1000} seconds`);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.err('RUST updateBlockTemplates failed. ' + (e instanceof Error ? e.message : e));
 | 
			
		||||
@ -423,6 +423,7 @@ class MempoolBlocks {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const lastBlockIndex = blocks.length - 1;
 | 
			
		||||
    let hasBlockStack = blocks.length >= 8;
 | 
			
		||||
    let stackWeight;
 | 
			
		||||
    let feeStatsCalculator: OnlineFeeStatsCalculator | void;
 | 
			
		||||
@ -430,7 +431,7 @@ class MempoolBlocks {
 | 
			
		||||
      if (blockWeights && blockWeights[7] !== null) {
 | 
			
		||||
        stackWeight = blockWeights[7];
 | 
			
		||||
      } else {
 | 
			
		||||
        stackWeight = blocks[blocks.length - 1].reduce((total, tx) => total + (mempool[tx]?.weight || 0), 0);
 | 
			
		||||
        stackWeight = blocks[lastBlockIndex].reduce((total, tx) => total + (mempool[tx]?.weight || 0), 0);
 | 
			
		||||
      }
 | 
			
		||||
      hasBlockStack = stackWeight > config.MEMPOOL.BLOCK_WEIGHT_UNITS;
 | 
			
		||||
      feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5, [10, 20, 30, 40, 50, 60, 70, 80, 90]);
 | 
			
		||||
@ -438,8 +439,8 @@ class MempoolBlocks {
 | 
			
		||||
 | 
			
		||||
    for (const cluster of Object.values(clusters)) {
 | 
			
		||||
      for (const memberTxid of cluster) {
 | 
			
		||||
        if (memberTxid in mempool) {
 | 
			
		||||
          const mempoolTx = mempool[memberTxid];
 | 
			
		||||
        const mempoolTx = mempool[memberTxid];
 | 
			
		||||
        if (mempoolTx) {
 | 
			
		||||
          const ancestors: Ancestor[] = [];
 | 
			
		||||
          const descendants: Ancestor[] = [];
 | 
			
		||||
          let matched = false;
 | 
			
		||||
@ -459,10 +460,7 @@ class MempoolBlocks {
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
          mempoolTx.ancestors = ancestors;
 | 
			
		||||
          mempoolTx.descendants = descendants;
 | 
			
		||||
          mempoolTx.bestDescendant = null;
 | 
			
		||||
          mempoolTx.cpfpChecked = true;
 | 
			
		||||
          Object.assign(mempoolTx, {ancestors, descendants, bestDescendant: null, cpfpChecked: true});
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -498,7 +496,7 @@ class MempoolBlocks {
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // online calculation of stack-of-blocks fee stats
 | 
			
		||||
          if (hasBlockStack && blockIndex === blocks.length - 1 && feeStatsCalculator) {
 | 
			
		||||
          if (hasBlockStack && blockIndex === lastBlockIndex && feeStatsCalculator) {
 | 
			
		||||
            feeStatsCalculator.processNext(mempoolTx);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
@ -518,7 +516,7 @@ class MempoolBlocks {
 | 
			
		||||
        totalSize,
 | 
			
		||||
        totalWeight,
 | 
			
		||||
        totalFees,
 | 
			
		||||
        feeStats: (hasBlockStack && blockIndex === blocks.length - 1 && feeStatsCalculator) ? feeStatsCalculator.getRawFeeStats() : undefined,
 | 
			
		||||
        feeStats: (hasBlockStack && blockIndex === lastBlockIndex && feeStatsCalculator) ? feeStatsCalculator.getRawFeeStats() : undefined,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ class Mempool {
 | 
			
		||||
                                                    maxmempool: 300000000, mempoolminfee: 0.00001000, minrelaytxfee: 0.00001000 };
 | 
			
		||||
  private mempoolChangedCallback: ((newMempool: {[txId: string]: MempoolTransactionExtended; }, newTransactions: MempoolTransactionExtended[],
 | 
			
		||||
    deletedTransactions: MempoolTransactionExtended[]) => void) | undefined;
 | 
			
		||||
  private $asyncMempoolChangedCallback: ((newMempool: {[txId: string]: MempoolTransactionExtended; }, newTransactions: MempoolTransactionExtended[],
 | 
			
		||||
  private $asyncMempoolChangedCallback: ((newMempool: {[txId: string]: MempoolTransactionExtended; }, mempoolSize: number, newTransactions: MempoolTransactionExtended[],
 | 
			
		||||
    deletedTransactions: MempoolTransactionExtended[]) => Promise<void>) | undefined;
 | 
			
		||||
 | 
			
		||||
  private txPerSecondArray: number[] = [];
 | 
			
		||||
@ -69,7 +69,7 @@ class Mempool {
 | 
			
		||||
    this.mempoolChangedCallback = fn;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public setAsyncMempoolChangedCallback(fn: (newMempool: { [txId: string]: MempoolTransactionExtended; },
 | 
			
		||||
  public setAsyncMempoolChangedCallback(fn: (newMempool: { [txId: string]: MempoolTransactionExtended; }, mempoolSize: number,
 | 
			
		||||
    newTransactions: MempoolTransactionExtended[], deletedTransactions: MempoolTransactionExtended[]) => Promise<void>): void {
 | 
			
		||||
    this.$asyncMempoolChangedCallback = fn;
 | 
			
		||||
  }
 | 
			
		||||
@ -84,16 +84,18 @@ class Mempool {
 | 
			
		||||
 | 
			
		||||
  public async $setMempool(mempoolData: { [txId: string]: MempoolTransactionExtended }) {
 | 
			
		||||
    this.mempoolCache = mempoolData;
 | 
			
		||||
    let count = 0;
 | 
			
		||||
    for (const txid of Object.keys(this.mempoolCache)) {
 | 
			
		||||
      if (this.mempoolCache[txid].sigops == null || this.mempoolCache[txid].effectiveFeePerVsize == null) {
 | 
			
		||||
        this.mempoolCache[txid] = transactionUtils.extendMempoolTransaction(this.mempoolCache[txid]);
 | 
			
		||||
      }
 | 
			
		||||
      count++;
 | 
			
		||||
    }
 | 
			
		||||
    if (this.mempoolChangedCallback) {
 | 
			
		||||
      this.mempoolChangedCallback(this.mempoolCache, [], []);
 | 
			
		||||
    }
 | 
			
		||||
    if (this.$asyncMempoolChangedCallback) {
 | 
			
		||||
      await this.$asyncMempoolChangedCallback(this.mempoolCache, [], []);
 | 
			
		||||
      await this.$asyncMempoolChangedCallback(this.mempoolCache, count, [], []);
 | 
			
		||||
    }
 | 
			
		||||
    this.addToSpendMap(Object.values(this.mempoolCache));
 | 
			
		||||
  }
 | 
			
		||||
@ -237,23 +239,24 @@ class Mempool {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const newMempoolSize = currentMempoolSize + newTransactions.length - deletedTransactions.length;
 | 
			
		||||
    const newTransactionsStripped = newTransactions.map((tx) => Common.stripTransaction(tx));
 | 
			
		||||
    this.latestTransactions = newTransactionsStripped.concat(this.latestTransactions).slice(0, 6);
 | 
			
		||||
 | 
			
		||||
    if (!this.inSync && transactions.length === Object.keys(this.mempoolCache).length) {
 | 
			
		||||
    if (!this.inSync && transactions.length === newMempoolSize) {
 | 
			
		||||
      this.inSync = true;
 | 
			
		||||
      logger.notice('The mempool is now in sync!');
 | 
			
		||||
      loadingIndicators.setProgress('mempool', 100);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.mempoolCacheDelta = Math.abs(transactions.length - Object.keys(this.mempoolCache).length);
 | 
			
		||||
    this.mempoolCacheDelta = Math.abs(transactions.length - newMempoolSize);
 | 
			
		||||
 | 
			
		||||
    if (this.mempoolChangedCallback && (hasChange || deletedTransactions.length)) {
 | 
			
		||||
      this.mempoolChangedCallback(this.mempoolCache, newTransactions, deletedTransactions);
 | 
			
		||||
    }
 | 
			
		||||
    if (this.$asyncMempoolChangedCallback && (hasChange || deletedTransactions.length)) {
 | 
			
		||||
      this.updateTimerProgress(timer, 'running async mempool callback');
 | 
			
		||||
      await this.$asyncMempoolChangedCallback(this.mempoolCache, newTransactions, deletedTransactions);
 | 
			
		||||
      await this.$asyncMempoolChangedCallback(this.mempoolCache, newMempoolSize, newTransactions, deletedTransactions);
 | 
			
		||||
      this.updateTimerProgress(timer, 'completed async mempool callback');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -333,7 +333,7 @@ class WebsocketHandler {
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async $handleMempoolChange(newMempool: { [txid: string]: MempoolTransactionExtended },
 | 
			
		||||
  async $handleMempoolChange(newMempool: { [txid: string]: MempoolTransactionExtended }, mempoolSize: number,
 | 
			
		||||
    newTransactions: MempoolTransactionExtended[], deletedTransactions: MempoolTransactionExtended[]): Promise<void> {
 | 
			
		||||
    if (!this.wss) {
 | 
			
		||||
      throw new Error('WebSocket.Server is not set');
 | 
			
		||||
@ -343,7 +343,7 @@ class WebsocketHandler {
 | 
			
		||||
 | 
			
		||||
    if (config.MEMPOOL.ADVANCED_GBT_MEMPOOL) {
 | 
			
		||||
      if (config.MEMPOOL.RUST_GBT) {
 | 
			
		||||
        await mempoolBlocks.$rustUpdateBlockTemplates(newMempool, newTransactions, deletedTransactions);
 | 
			
		||||
        await mempoolBlocks.$rustUpdateBlockTemplates(newMempool, mempoolSize, newTransactions, deletedTransactions);
 | 
			
		||||
      } else {
 | 
			
		||||
        await mempoolBlocks.$updateBlockTemplates(newMempool, newTransactions, deletedTransactions, true);
 | 
			
		||||
      }
 | 
			
		||||
@ -664,7 +664,7 @@ class WebsocketHandler {
 | 
			
		||||
 | 
			
		||||
    if (config.MEMPOOL.ADVANCED_GBT_MEMPOOL) {
 | 
			
		||||
      if (config.MEMPOOL.RUST_GBT) {
 | 
			
		||||
        await mempoolBlocks.$rustUpdateBlockTemplates(_memPool, [], transactions);
 | 
			
		||||
        await mempoolBlocks.$rustUpdateBlockTemplates(_memPool, Object.keys(_memPool).length, [], transactions);
 | 
			
		||||
      } else {
 | 
			
		||||
        await mempoolBlocks.$makeBlockTemplates(_memPool, true);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user