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