optimize cpfp indexing
This commit is contained in:
		
							parent
							
								
									ab5308e1c8
								
							
						
					
					
						commit
						f2ad184d1f
					
				| @ -27,6 +27,7 @@ import mining from './mining/mining'; | |||||||
| import DifficultyAdjustmentsRepository from '../repositories/DifficultyAdjustmentsRepository'; | import DifficultyAdjustmentsRepository from '../repositories/DifficultyAdjustmentsRepository'; | ||||||
| import PricesRepository from '../repositories/PricesRepository'; | import PricesRepository from '../repositories/PricesRepository'; | ||||||
| import priceUpdater from '../tasks/price-updater'; | import priceUpdater from '../tasks/price-updater'; | ||||||
|  | import { Block } from 'bitcoinjs-lib'; | ||||||
| 
 | 
 | ||||||
| class Blocks { | class Blocks { | ||||||
|   private blocks: BlockExtended[] = []; |   private blocks: BlockExtended[] = []; | ||||||
| @ -342,7 +343,7 @@ class Blocks { | |||||||
| 
 | 
 | ||||||
|       for (const block of unindexedBlocks) { |       for (const block of unindexedBlocks) { | ||||||
|         // Logging
 |         // Logging
 | ||||||
|         const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - timer)); |         const elapsedSeconds = Math.max(1, new Date().getTime() / 1000 - timer); | ||||||
|         if (elapsedSeconds > 5) { |         if (elapsedSeconds > 5) { | ||||||
|           const runningFor = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt)); |           const runningFor = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt)); | ||||||
|           const blockPerSeconds = Math.max(1, countThisRun / elapsedSeconds); |           const blockPerSeconds = Math.max(1, countThisRun / elapsedSeconds); | ||||||
| @ -352,10 +353,11 @@ class Blocks { | |||||||
|           countThisRun = 0; |           countThisRun = 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         await this.$indexCPFP(block.hash); // Calculate and save CPFP data for transactions in this block
 |         await this.$indexCPFP(block.hash, block.height); // Calculate and save CPFP data for transactions in this block
 | ||||||
| 
 | 
 | ||||||
|         // Logging
 |         // Logging
 | ||||||
|         count++; |         count++; | ||||||
|  |         countThisRun++; | ||||||
|       } |       } | ||||||
|       if (count > 0) { |       if (count > 0) { | ||||||
|         logger.notice(`CPFP indexing completed: indexed ${count} blocks`); |         logger.notice(`CPFP indexing completed: indexed ${count} blocks`); | ||||||
| @ -411,7 +413,7 @@ class Blocks { | |||||||
|           } |           } | ||||||
|           ++indexedThisRun; |           ++indexedThisRun; | ||||||
|           ++totalIndexed; |           ++totalIndexed; | ||||||
|           const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - timer)); |           const elapsedSeconds = Math.max(1, new Date().getTime() / 1000 - timer); | ||||||
|           if (elapsedSeconds > 5 || blockHeight === lastBlockToIndex) { |           if (elapsedSeconds > 5 || blockHeight === lastBlockToIndex) { | ||||||
|             const runningFor = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt)); |             const runningFor = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt)); | ||||||
|             const blockPerSeconds = Math.max(1, indexedThisRun / elapsedSeconds); |             const blockPerSeconds = Math.max(1, indexedThisRun / elapsedSeconds); | ||||||
| @ -518,7 +520,7 @@ class Blocks { | |||||||
|               const newBlock = await this.$indexBlock(lastBlock['height'] - i); |               const newBlock = await this.$indexBlock(lastBlock['height'] - i); | ||||||
|               await this.$getStrippedBlockTransactions(newBlock.id, true, true); |               await this.$getStrippedBlockTransactions(newBlock.id, true, true); | ||||||
|               if (config.MEMPOOL.TRANSACTION_INDEXING) { |               if (config.MEMPOOL.TRANSACTION_INDEXING) { | ||||||
|                 await this.$indexCPFP(newBlock.id); |                 await this.$indexCPFP(newBlock.id, lastBlock['height'] - i); | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|             await mining.$indexDifficultyAdjustments(); |             await mining.$indexDifficultyAdjustments(); | ||||||
| @ -546,7 +548,7 @@ class Blocks { | |||||||
|             await this.$getStrippedBlockTransactions(blockExtended.id, true); |             await this.$getStrippedBlockTransactions(blockExtended.id, true); | ||||||
|           } |           } | ||||||
|           if (config.MEMPOOL.TRANSACTION_INDEXING) { |           if (config.MEMPOOL.TRANSACTION_INDEXING) { | ||||||
|             this.$indexCPFP(blockExtended.id); |             this.$indexCPFP(blockExtended.id, this.currentBlockHeight); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @ -738,23 +740,47 @@ class Blocks { | |||||||
|     return this.currentBlockHeight; |     return this.currentBlockHeight; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   public async $indexCPFP(hash: string): Promise<void> { |   public async $indexCPFP(hash: string, height: number): Promise<void> { | ||||||
|     const block = await bitcoinClient.getBlock(hash, 2); |     let transactions; | ||||||
|     const transactions = block.tx; |     if (Common.blocksSummariesIndexingEnabled()) { | ||||||
|     let cluster: IBitcoinApi.VerboseTransaction[] = []; |       transactions = await this.$getStrippedBlockTransactions(hash); | ||||||
|  |       const rawBlock = await bitcoinClient.getBlock(hash, 0); | ||||||
|  |       const block = Block.fromHex(rawBlock); | ||||||
|  |       const txMap = {}; | ||||||
|  |       for (const tx of block.transactions || []) { | ||||||
|  |         txMap[tx.getId()] = tx; | ||||||
|  |       } | ||||||
|  |       for (const tx of transactions) { | ||||||
|  |         if (txMap[tx.txid]?.ins) { | ||||||
|  |           tx.vin = txMap[tx.txid].ins.map(vin => { | ||||||
|  |             return { | ||||||
|  |               txid: vin.hash | ||||||
|  |             }; | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       const block = await bitcoinClient.getBlock(hash, 2); | ||||||
|  |       transactions = block.tx.map(tx => { | ||||||
|  |         tx.vsize = tx.weight / 4; | ||||||
|  |         return tx; | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   | ||||||
|  |     let cluster: TransactionStripped[] = []; | ||||||
|     let ancestors: { [txid: string]: boolean } = {}; |     let ancestors: { [txid: string]: boolean } = {}; | ||||||
|     for (let i = transactions.length - 1; i >= 0; i--) { |     for (let i = transactions.length - 1; i >= 0; i--) { | ||||||
|       const tx = transactions[i]; |       const tx = transactions[i]; | ||||||
|       if (!ancestors[tx.txid]) { |       if (!ancestors[tx.txid]) { | ||||||
|         let totalFee = 0; |         let totalFee = 0; | ||||||
|         let totalWeight = 0; |         let totalVSize = 0; | ||||||
|         cluster.forEach(tx => { |         cluster.forEach(tx => { | ||||||
|           totalFee += tx?.fee || 0; |           totalFee += tx?.fee || 0; | ||||||
|           totalWeight += tx.weight; |           totalVSize += tx.vsize; | ||||||
|         }); |         }); | ||||||
|         const effectiveFeePerVsize = (totalFee * 100_000_000) / (totalWeight / 4); |         const effectiveFeePerVsize = (totalFee * 100_000_000) / totalVSize; | ||||||
|         if (cluster.length > 1) { |         if (cluster.length > 1) { | ||||||
|           await cpfpRepository.$saveCluster(block.height, cluster.map(tx => { return { txid: tx.txid, weight: tx.weight, fee: (tx.fee || 0) * 100_000_000 }; }), effectiveFeePerVsize); |           await cpfpRepository.$saveCluster(height, cluster.map(tx => { return { txid: tx.txid, weight: tx.vsize * 4, fee: (tx.fee || 0) * 100_000_000 }; }), effectiveFeePerVsize); | ||||||
|           for (const tx of cluster) { |           for (const tx of cluster) { | ||||||
|             await transactionRepository.$setCluster(tx.txid, cluster[0].txid); |             await transactionRepository.$setCluster(tx.txid, cluster[0].txid); | ||||||
|           } |           } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user