Add local acceleration info APIs
This commit is contained in:
parent
130bdac58c
commit
bd0de745e2
@ -8,6 +8,7 @@ import HashratesRepository from '../../repositories/HashratesRepository';
|
|||||||
import bitcoinClient from '../bitcoin/bitcoin-client';
|
import bitcoinClient from '../bitcoin/bitcoin-client';
|
||||||
import mining from "./mining";
|
import mining from "./mining";
|
||||||
import PricesRepository from '../../repositories/PricesRepository';
|
import PricesRepository from '../../repositories/PricesRepository';
|
||||||
|
import AccelerationRepository from '../../repositories/AccelerationRepository';
|
||||||
|
|
||||||
class MiningRoutes {
|
class MiningRoutes {
|
||||||
public initRoutes(app: Application) {
|
public initRoutes(app: Application) {
|
||||||
@ -34,6 +35,10 @@ class MiningRoutes {
|
|||||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/:hash', this.$getBlockAudit)
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/:hash', this.$getBlockAudit)
|
||||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/timestamp/:timestamp', this.$getHeightFromTimestamp)
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/timestamp/:timestamp', this.$getHeightFromTimestamp)
|
||||||
.get(config.MEMPOOL.API_URL_PREFIX + 'historical-price', this.$getHistoricalPrice)
|
.get(config.MEMPOOL.API_URL_PREFIX + 'historical-price', this.$getHistoricalPrice)
|
||||||
|
|
||||||
|
.get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/pool/:slug', this.$getAccelerationsByPool)
|
||||||
|
.get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/block/:height', this.$getAccelerationsByHeight)
|
||||||
|
.get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/recent/:interval', this.$getRecentAccelerations)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,6 +357,52 @@ class MiningRoutes {
|
|||||||
res.status(500).send(e instanceof Error ? e.message : e);
|
res.status(500).send(e instanceof Error ? e.message : e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async $getAccelerationsByPool(req: Request, res: Response): Promise<void> {
|
||||||
|
try {
|
||||||
|
res.header('Pragma', 'public');
|
||||||
|
res.header('Cache-control', 'public');
|
||||||
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
|
res.status(400).send('Acceleration data is not available.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
res.status(200).send(await AccelerationRepository.$getAccelerationInfo(req.params.slug));
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).send(e instanceof Error ? e.message : e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async $getAccelerationsByHeight(req: Request, res: Response): Promise<void> {
|
||||||
|
try {
|
||||||
|
res.header('Pragma', 'public');
|
||||||
|
res.header('Cache-control', 'public');
|
||||||
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24).toUTCString());
|
||||||
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
|
res.status(400).send('Acceleration data is not available.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const height = req.params.height === undefined ? undefined : parseInt(req.params.height, 10);
|
||||||
|
res.status(200).send(await AccelerationRepository.$getAccelerationInfo(null, height));
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).send(e instanceof Error ? e.message : e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async $getRecentAccelerations(req: Request, res: Response): Promise<void> {
|
||||||
|
try {
|
||||||
|
res.header('Pragma', 'public');
|
||||||
|
res.header('Cache-control', 'public');
|
||||||
|
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
|
||||||
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
|
||||||
|
res.status(400).send('Acceleration data is not available.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
res.status(200).send(await AccelerationRepository.$getAccelerationInfo(null, null, req.params.interval));
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).send(e instanceof Error ? e.message : e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new MiningRoutes();
|
export default new MiningRoutes();
|
||||||
|
@ -3,6 +3,22 @@ import { ResultSetHeader, RowDataPacket } from 'mysql2';
|
|||||||
import DB from '../database';
|
import DB from '../database';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
import { IEsploraApi } from '../api/bitcoin/esplora-api.interface';
|
import { IEsploraApi } from '../api/bitcoin/esplora-api.interface';
|
||||||
|
import { Common } from '../api/common';
|
||||||
|
import config from '../config';
|
||||||
|
|
||||||
|
export interface PublicAcceleration {
|
||||||
|
txid: string,
|
||||||
|
height: number,
|
||||||
|
pool: {
|
||||||
|
id: number,
|
||||||
|
slug: string,
|
||||||
|
name: string,
|
||||||
|
},
|
||||||
|
effective_vsize: number,
|
||||||
|
effective_fee: number,
|
||||||
|
boost_rate: number,
|
||||||
|
boost_cost: number,
|
||||||
|
}
|
||||||
|
|
||||||
class AccelerationRepository {
|
class AccelerationRepository {
|
||||||
public async $saveAcceleration(acceleration: AccelerationInfo, block: IEsploraApi.Block, pool_id: number): Promise<void> {
|
public async $saveAcceleration(acceleration: AccelerationInfo, block: IEsploraApi.Block, pool_id: number): Promise<void> {
|
||||||
@ -38,6 +54,56 @@ class AccelerationRepository {
|
|||||||
// We don't throw, not a critical issue if we miss some accelerations
|
// We don't throw, not a critical issue if we miss some accelerations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async $getAccelerationInfo(poolSlug: string | null = null, height: number | null = null, interval: string | null = null): Promise<PublicAcceleration[]> {
|
||||||
|
interval = Common.getSqlInterval(interval);
|
||||||
|
|
||||||
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || (interval == null && poolSlug == null && height == null)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let query = `
|
||||||
|
SELECT * FROM accelerations
|
||||||
|
JOIN pools on pools.unique_id = accelerations.pool
|
||||||
|
`;
|
||||||
|
let params: any[] = [];
|
||||||
|
|
||||||
|
if (interval) {
|
||||||
|
query += ` WHERE accelerations.added BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW() `;
|
||||||
|
} else if (height != null) {
|
||||||
|
query += ` WHERE accelerations.height = ? `;
|
||||||
|
params.push(height);
|
||||||
|
} else if (poolSlug != null) {
|
||||||
|
query += ` WHERE pools.slug = ? `;
|
||||||
|
params.push(poolSlug);
|
||||||
|
}
|
||||||
|
|
||||||
|
query += ` ORDER BY accelerations.added DESC `;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [rows] = await DB.query(query, params) as RowDataPacket[][];
|
||||||
|
if (rows?.length) {
|
||||||
|
return rows.map(row => ({
|
||||||
|
txid: row.txid,
|
||||||
|
height: row.height,
|
||||||
|
pool: {
|
||||||
|
id: row.id,
|
||||||
|
slug: row.slug,
|
||||||
|
name: row.name,
|
||||||
|
},
|
||||||
|
effective_vsize: row.effective_vsize,
|
||||||
|
effective_fee: row.effective_fee,
|
||||||
|
boost_rate: row.boost_rate,
|
||||||
|
boost_cost: row.boost_cost,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Cannot query acceleration info. Reason: ` + (e instanceof Error ? e.message : e));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new AccelerationRepository();
|
export default new AccelerationRepository();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user