List orphaned blocks in the new blocks-bulk API
This commit is contained in:
		
							parent
							
								
									458f24c9f2
								
							
						
					
					
						commit
						281899f551
					
				| @ -25,6 +25,7 @@ import mining from './mining/mining'; | ||||
| import DifficultyAdjustmentsRepository from '../repositories/DifficultyAdjustmentsRepository'; | ||||
| import PricesRepository from '../repositories/PricesRepository'; | ||||
| import priceUpdater from '../tasks/price-updater'; | ||||
| import chainTips from './chain-tips'; | ||||
| 
 | ||||
| class Blocks { | ||||
|   private blocks: BlockExtended[] = []; | ||||
| @ -171,6 +172,7 @@ class Blocks { | ||||
|     blk.extras.coinbaseRaw = blk.extras.coinbaseTx.vin[0].scriptsig; | ||||
|     blk.extras.usd = priceUpdater.latestPrices.USD; | ||||
|     blk.extras.medianTimestamp = block.medianTime; | ||||
|     blk.extras.orphans = chainTips.getOrphanedBlocksAtHeight(blk.height); | ||||
| 
 | ||||
|     if (block.height === 0) { | ||||
|       blk.extras.medianFee = 0; // 50th percentiles
 | ||||
| @ -204,7 +206,6 @@ class Blocks { | ||||
|     } | ||||
| 
 | ||||
|     blk.extras.blockTime = 0; // TODO
 | ||||
|     blk.extras.orphaned = false; // TODO
 | ||||
| 
 | ||||
|     blk.extras.feePercentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(block.id); | ||||
|     if (blk.extras.feePercentiles !== null) { | ||||
| @ -545,6 +546,7 @@ class Blocks { | ||||
|       } else { | ||||
|         this.currentBlockHeight++; | ||||
|         logger.debug(`New block found (#${this.currentBlockHeight})!`); | ||||
|         await chainTips.updateOrphanedBlocks(); | ||||
|       } | ||||
| 
 | ||||
|       const blockHash = await bitcoinApi.$getBlockHash(this.currentBlockHeight); | ||||
| @ -812,6 +814,10 @@ class Blocks { | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       // Re-org can happen after indexing so we need to always get the
 | ||||
|       // latest state from core
 | ||||
|       block.orphans = chainTips.getOrphanedBlocksAtHeight(block.height); | ||||
| 
 | ||||
|       blocks.push(block); | ||||
|       fromHeight++; | ||||
|     } | ||||
|  | ||||
							
								
								
									
										53
									
								
								backend/src/api/chain-tips.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								backend/src/api/chain-tips.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| import logger from "../logger"; | ||||
| import bitcoinClient from "./bitcoin/bitcoin-client"; | ||||
| 
 | ||||
| export interface ChainTip { | ||||
|   height: number; | ||||
|   hash: string; | ||||
|   branchlen: number; | ||||
|   status: 'invalid' | 'active' | 'valid-fork' | 'valid-headers' | 'headers-only'; | ||||
| }; | ||||
| 
 | ||||
| export interface OrphanedBlock { | ||||
|   height: number; | ||||
|   hash: string; | ||||
|   status: 'valid-fork' | 'valid-headers' | 'headers-only'; | ||||
| } | ||||
| 
 | ||||
| class ChainTips { | ||||
|   private chainTips: ChainTip[] = []; | ||||
|   private orphanedBlocks: OrphanedBlock[] = []; | ||||
| 
 | ||||
|   public async updateOrphanedBlocks(): Promise<void> { | ||||
|     this.chainTips = await bitcoinClient.getChainTips(); | ||||
|     this.orphanedBlocks = []; | ||||
| 
 | ||||
|     for (const chain of this.chainTips) { | ||||
|       if (chain.status === 'valid-fork' || chain.status === 'valid-headers' || chain.status === 'headers-only') { | ||||
|         let block = await bitcoinClient.getBlock(chain.hash); | ||||
|         while (block && block.confirmations === -1) { | ||||
|           this.orphanedBlocks.push({ | ||||
|             height: block.height, | ||||
|             hash: block.hash, | ||||
|             status: chain.status | ||||
|           }); | ||||
|           block = await bitcoinClient.getBlock(block.previousblockhash); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     logger.debug(`Updated orphaned blocks cache. Found ${this.orphanedBlocks.length} orphaned blocks`); | ||||
|   } | ||||
| 
 | ||||
|   public getOrphanedBlocksAtHeight(height: number): OrphanedBlock[] { | ||||
|     const orphans: OrphanedBlock[] = []; | ||||
|     for (const block of this.orphanedBlocks) { | ||||
|       if (block.height === height) { | ||||
|         orphans.push(block); | ||||
|       } | ||||
|     } | ||||
|     return orphans; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export default new ChainTips(); | ||||
| @ -37,6 +37,7 @@ import fundingTxFetcher from './tasks/lightning/sync-tasks/funding-tx-fetcher'; | ||||
| import forensicsService from './tasks/lightning/forensics.service'; | ||||
| import priceUpdater from './tasks/price-updater'; | ||||
| import mining from './api/mining/mining'; | ||||
| import chainTips from './api/chain-tips'; | ||||
| import { AxiosError } from 'axios'; | ||||
| 
 | ||||
| class Server { | ||||
| @ -134,6 +135,7 @@ class Server { | ||||
|     } | ||||
| 
 | ||||
|     priceUpdater.$run(); | ||||
|     await chainTips.updateOrphanedBlocks(); | ||||
| 
 | ||||
|     this.setUpHttpApiRoutes(); | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import { IEsploraApi } from './api/bitcoin/esplora-api.interface'; | ||||
| import { OrphanedBlock } from './api/chain-tips'; | ||||
| import { HeapNode } from "./utils/pairing-heap"; | ||||
| 
 | ||||
| export interface PoolTag { | ||||
| @ -163,7 +164,7 @@ export interface BlockExtension { | ||||
|   usd?: number | null; | ||||
|   medianTimestamp?: number; | ||||
|   blockTime?: number; | ||||
|   orphaned?: boolean; | ||||
|   orphans?: OrphanedBlock[] | null; | ||||
|   coinbaseAddress?: string | null; | ||||
|   coinbaseSignature?: string | null; | ||||
|   virtualSize?: number; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user