mirror of
https://github.com/mempool/mempool.git
synced 2026-08-13 12:33:11 +02:00
add: flag values endpoints
This commit is contained in:
parent
25ae5109b9
commit
1af9dfd457
1 changed files with 61 additions and 0 deletions
|
|
@ -23,12 +23,14 @@ import { calculateMempoolTxCpfp } from '../cpfp';
|
||||||
import { handleError } from '../../utils/api';
|
import { handleError } from '../../utils/api';
|
||||||
import poolsUpdater from '../../tasks/pools-updater';
|
import poolsUpdater from '../../tasks/pools-updater';
|
||||||
import chainTips from '../chain-tips';
|
import chainTips from '../chain-tips';
|
||||||
|
import FlagValueRepository, { INTERVAL_PRESETS } from '../../repositories/FlagValueRepository';
|
||||||
|
|
||||||
const TXID_REGEX = /^[a-f0-9]{64}$/i;
|
const TXID_REGEX = /^[a-f0-9]{64}$/i;
|
||||||
const BLOCK_HASH_REGEX = /^[a-f0-9]{64}$/i;
|
const BLOCK_HASH_REGEX = /^[a-f0-9]{64}$/i;
|
||||||
const ADDRESS_REGEX = /^[a-z0-9]{2,120}$/i;
|
const ADDRESS_REGEX = /^[a-z0-9]{2,120}$/i;
|
||||||
const SCRIPT_HASH_REGEX = /^([a-f0-9]{2})+$/i;
|
const SCRIPT_HASH_REGEX = /^([a-f0-9]{2})+$/i;
|
||||||
const MAX_TRANSACTION_TIMES = 100;
|
const MAX_TRANSACTION_TIMES = 100;
|
||||||
|
const JUST_NUMBERS_REGEX = /^[1-9]\d*$/;
|
||||||
|
|
||||||
class BitcoinRoutes {
|
class BitcoinRoutes {
|
||||||
public initRoutes(app: Application) {
|
public initRoutes(app: Application) {
|
||||||
|
|
@ -70,6 +72,10 @@ class BitcoinRoutes {
|
||||||
.get(config.MEMPOOL.API_URL_PREFIX + 'internal/blocks/definition/list', this.getBlockDefinitionHashes)
|
.get(config.MEMPOOL.API_URL_PREFIX + 'internal/blocks/definition/list', this.getBlockDefinitionHashes)
|
||||||
.get(config.MEMPOOL.API_URL_PREFIX + 'internal/blocks/definition/current', this.getCurrentBlockDefinitionHash)
|
.get(config.MEMPOOL.API_URL_PREFIX + 'internal/blocks/definition/current', this.getCurrentBlockDefinitionHash)
|
||||||
.get(config.MEMPOOL.API_URL_PREFIX + 'internal/blocks/:definitionHash', this.getBlocksByDefinitionHash)
|
.get(config.MEMPOOL.API_URL_PREFIX + 'internal/blocks/:definitionHash', this.getBlocksByDefinitionHash)
|
||||||
|
|
||||||
|
.get(config.MEMPOOL.API_URL_PREFIX + 'goggles/:interval/', this.getTxCountPerFlagValue)
|
||||||
|
.get(config.MEMPOOL.API_URL_PREFIX + 'goggles/:interval/:bucketSize', this.getTxCountPerFlagValue)
|
||||||
|
.get(config.MEMPOOL.API_URL_PREFIX + 'goggles/:interval/:bucketSize/:op/:mask', this.getTxCountPerFlagValue)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (config.MEMPOOL.BACKEND !== 'esplora') {
|
if (config.MEMPOOL.BACKEND !== 'esplora') {
|
||||||
|
|
@ -1132,6 +1138,61 @@ class BitcoinRoutes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async getTxCountPerFlagValue(req: Request, res: Response) {
|
||||||
|
try {
|
||||||
|
if (!Common.blocksSummariesIndexingEnabled()) {
|
||||||
|
handleError(req, res, 404, `Block summaries indexing is required for this API`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const presets = INTERVAL_PRESETS;
|
||||||
|
const operations = ['and', 'or', 'nor', undefined];
|
||||||
|
const intervals = Object.keys(presets);
|
||||||
|
const interval = req.params.interval;
|
||||||
|
|
||||||
|
if (!intervals.includes(interval)) {
|
||||||
|
handleError(req, res, 400, `Invalid interval, must be one of ${intervals.toString()}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const validBucketSizes = presets[interval].bucketSizes;
|
||||||
|
const rawBucketSize = req.params.bucketSize;
|
||||||
|
const bucketSize: number = rawBucketSize === undefined ? validBucketSizes[0] : Number(rawBucketSize);
|
||||||
|
if (!Number.isInteger(bucketSize) || !validBucketSizes.includes(bucketSize)) {
|
||||||
|
handleError(req, res, 400, `Invalid bucket size, must be ${validBucketSizes.toString()}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!operations.includes(req.params.op)) {
|
||||||
|
handleError(req, res, 400, `Invalid operation, must be 'and', 'or', 'nor' or undefined.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.params.mask && !JUST_NUMBERS_REGEX.test(req.params.mask)) {
|
||||||
|
handleError(req, res, 400, `Invalid mask value, must be a positive integer`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const op = (req.params.op) as 'and' | 'or' | 'nor' | undefined;
|
||||||
|
const mask = BigInt(req.params.mask ?? 0n);
|
||||||
|
|
||||||
|
const { tip } = await FlagValueRepository.$getTipAndTailIndexedByBucketSize(bucketSize) || { tip: undefined };
|
||||||
|
|
||||||
|
if (!tip) {
|
||||||
|
handleError(req, res, 400, `Failed to get latest indexed flag values for ${interval}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startHeight = presets[interval].retentionSpan !== -1 ? (tip - presets[interval].retentionSpan) : -1;
|
||||||
|
const txsCount = await FlagValueRepository.$queryTxCountBasedOnMask(mask, bucketSize, op, startHeight);
|
||||||
|
res.header('X-total-count', tip.toString());
|
||||||
|
res.header('Expires', new Date(Date.now() + 1000 * 3600 * 24 * (presets[interval].bucketSizes[0] / 144)).toUTCString());
|
||||||
|
res.send(txsCount);
|
||||||
|
} catch (e: any) {
|
||||||
|
handleError(req, res, 400, e instanceof Error ? e.message : 'Failed to get flag values');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async $postTransaction(req: Request, res: Response) {
|
private async $postTransaction(req: Request, res: Response) {
|
||||||
res.setHeader('content-type', 'text/plain');
|
res.setHeader('content-type', 'text/plain');
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue