Compare commits
9 Commits
master
...
nymkappa/h
Author | SHA1 | Date | |
---|---|---|---|
|
20d0df9d5c | ||
|
cef6127e69 | ||
|
6d945890f4 | ||
|
5922c616df | ||
|
14d8f67878 | ||
|
f80c0738b2 | ||
|
545b3e7325 | ||
|
3c23e3ff84 | ||
|
8a51f32e63 |
@ -6,7 +6,7 @@ import websocketHandler from '../websocket-handler';
|
|||||||
import mempool from '../mempool';
|
import mempool from '../mempool';
|
||||||
import feeApi from '../fee-api';
|
import feeApi from '../fee-api';
|
||||||
import mempoolBlocks from '../mempool-blocks';
|
import mempoolBlocks from '../mempool-blocks';
|
||||||
import bitcoinApi from './bitcoin-api-factory';
|
import bitcoinApi, { bitcoinCoreApi } from './bitcoin-api-factory';
|
||||||
import { Common } from '../common';
|
import { Common } from '../common';
|
||||||
import backendInfo from '../backend-info';
|
import backendInfo from '../backend-info';
|
||||||
import transactionUtils from '../transaction-utils';
|
import transactionUtils from '../transaction-utils';
|
||||||
@ -21,6 +21,7 @@ import transactionRepository from '../../repositories/TransactionRepository';
|
|||||||
import rbfCache from '../rbf-cache';
|
import rbfCache from '../rbf-cache';
|
||||||
import { calculateMempoolTxCpfp } from '../cpfp';
|
import { calculateMempoolTxCpfp } from '../cpfp';
|
||||||
import { handleError } from '../../utils/api';
|
import { handleError } from '../../utils/api';
|
||||||
|
import BlocksRepository from '../../repositories/BlocksRepository';
|
||||||
|
|
||||||
class BitcoinRoutes {
|
class BitcoinRoutes {
|
||||||
public initRoutes(app: Application) {
|
public initRoutes(app: Application) {
|
||||||
@ -80,8 +81,87 @@ class BitcoinRoutes {
|
|||||||
.get(config.MEMPOOL.API_URL_PREFIX + 'address-prefix/:prefix', this.getAddressPrefix)
|
.get(config.MEMPOOL.API_URL_PREFIX + 'address-prefix/:prefix', this.getAddressPrefix)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.get('/api/internal/health', this.generateHealthReport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async generateHealthReport(req: Request, res: Response): Promise<void> {
|
||||||
|
let response = {
|
||||||
|
core: {
|
||||||
|
height: -1
|
||||||
|
},
|
||||||
|
mempool: {
|
||||||
|
height: -1,
|
||||||
|
indexing: {
|
||||||
|
enabled: Common.indexingEnabled(),
|
||||||
|
blocks: {
|
||||||
|
count: -1,
|
||||||
|
progress: -1,
|
||||||
|
withCpfp: {
|
||||||
|
count: -1,
|
||||||
|
progress: -1,
|
||||||
|
},
|
||||||
|
withCoinStats: {
|
||||||
|
count: -1,
|
||||||
|
progress: -1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Bitcoin Core
|
||||||
|
let bitcoinCoreIndexes: number | string;
|
||||||
|
try {
|
||||||
|
bitcoinCoreIndexes = await bitcoinClient.getIndexInfo();
|
||||||
|
for (const indexName in bitcoinCoreIndexes as any) {
|
||||||
|
response.core[indexName.replace(/ /g,'_')] = bitcoinCoreIndexes[indexName];
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
response.core['error'] = e.message;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
response.core.height = await bitcoinCoreApi.$getBlockHeightTip();
|
||||||
|
} catch (e: any) {
|
||||||
|
response.core['error'] = e.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mempool
|
||||||
|
response.mempool.height = blocks.getCurrentBlockHeight();
|
||||||
|
if (Common.indexingEnabled()) {
|
||||||
|
const indexingBlockAmount = (config.MEMPOOL.INDEXING_BLOCKS_AMOUNT === -1 ? response.core.height : config.MEMPOOL.INDEXING_BLOCKS_AMOUNT);
|
||||||
|
const computeProgress = (count: number): number => Math.min(1.0, Math.round(count / indexingBlockAmount * 100) / 100);
|
||||||
|
response.mempool.indexing.blocks.count = await BlocksRepository.$getIndexedBlockCount();
|
||||||
|
response.mempool.indexing.blocks.progress = computeProgress(response.mempool.indexing.blocks.count);
|
||||||
|
response.mempool.indexing.blocks.withCpfp.count = await BlocksRepository.$getIndexedCpfpBlockCount();
|
||||||
|
response.mempool.indexing.blocks.withCpfp.progress = computeProgress(response.mempool.indexing.blocks.withCpfp.count);
|
||||||
|
response.mempool.indexing.blocks.withCoinStats.count = await BlocksRepository.$getIndexedCoinStatsBlockCount();
|
||||||
|
response.mempool.indexing.blocks.withCoinStats.progress = computeProgress(response.mempool.indexing.blocks.withCoinStats.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Esplora
|
||||||
|
if (config.MEMPOOL.BACKEND === 'esplora') {
|
||||||
|
try {
|
||||||
|
response['esplora'] = {
|
||||||
|
height: await bitcoinApi.$getBlockHeightTip()
|
||||||
|
};
|
||||||
|
} catch (e: any) {
|
||||||
|
response['esplora'] = {
|
||||||
|
height: -1,
|
||||||
|
error: e.message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(response);
|
||||||
|
|
||||||
|
} catch (e: any) {
|
||||||
|
logger.err(`Unable to generate health report. Exception: ${JSON.stringify(e)}`);
|
||||||
|
logger.err(e.stack);
|
||||||
|
res.status(500).send(e instanceof Error ? e.message : e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private getInitData(req: Request, res: Response) {
|
private getInitData(req: Request, res: Response) {
|
||||||
try {
|
try {
|
||||||
|
@ -1153,6 +1153,57 @@ class BlocksRepository {
|
|||||||
blk.extras = <BlockExtension>extras;
|
blk.extras = <BlockExtension>extras;
|
||||||
return <BlockExtended>blk;
|
return <BlockExtended>blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count how many blocks are indexed
|
||||||
|
*/
|
||||||
|
public async $getIndexedBlockCount(): Promise<number> {
|
||||||
|
try {
|
||||||
|
const [res]: any[] = await DB.query(`SELECT COUNT(hash) as count FROM blocks`);
|
||||||
|
if (!res || !res.length) {
|
||||||
|
logger.err(`Unable to count indexed blocks in our db`);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res[0].count;
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Unable to count indexed blocks in our db. Exception: ${JSON.stringify(e)}`);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count how many blocks are indexed with CPFP data
|
||||||
|
*/
|
||||||
|
public async $getIndexedCpfpBlockCount(): Promise<number> {
|
||||||
|
try {
|
||||||
|
const [res]: any[] = await DB.query(`SELECT COUNT(DISTINCT height) as count FROM compact_cpfp_clusters`);
|
||||||
|
if (!res || !res.length) {
|
||||||
|
logger.err(`Unable to count indexed blocks with CPFP data in our db`);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res[0].count;
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Unable to count indexed blocks with CPFP data in our db. Exception: ${JSON.stringify(e)}`);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count how many blocks are indexed with coin stats data
|
||||||
|
*/
|
||||||
|
public async $getIndexedCoinStatsBlockCount(): Promise<number> {
|
||||||
|
try {
|
||||||
|
const [res]: any[] = await DB.query(`SELECT COUNT(hash) as count FROM blocks WHERE utxoset_size IS NOT NULL && total_input_amt IS NOT NULL`);
|
||||||
|
if (!res || !res.length) {
|
||||||
|
logger.err(`Unable to count indexed blocks with coin stats data in our db`);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res[0].count;
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Unable to count indexed blocks with coin stats data in our db. Exception: ${JSON.stringify(e)}`);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new BlocksRepository();
|
export default new BlocksRepository();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user