Get blocks data set by bulk (non indexed)

This commit is contained in:
nymkappa 2023-02-16 15:36:16 +09:00
parent 58eb6ccc8e
commit c44896f53e
No known key found for this signature in database
GPG Key ID: E155910B16E8BD04
3 changed files with 87 additions and 2 deletions

View File

@ -95,6 +95,8 @@ class BitcoinRoutes {
.get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/summary', this.getStrippedBlockTransactions)
.get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/audit-summary', this.getBlockAuditSummary)
.post(config.MEMPOOL.API_URL_PREFIX + 'psbt/addparents', this.postPsbtCompletion)
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from', this.getBlocksByBulk.bind(this))
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from/:to', this.getBlocksByBulk.bind(this))
;
if (config.MEMPOOL.BACKEND !== 'esplora') {
@ -402,6 +404,32 @@ class BitcoinRoutes {
}
}
private async getBlocksByBulk(req: Request, res: Response) {
try {
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false) { // Liquid, Bisq - Not implemented
return res.status(404).send(`Not implemented`);
}
const from = parseInt(req.params.from, 10);
if (!from) {
return res.status(400).send(`Parameter 'from' must be a block height (integer)`);
}
const to = req.params.to === undefined ? await bitcoinApi.$getBlockHeightTip() : parseInt(req.params.to, 10);
if (!to) {
return res.status(400).send(`Parameter 'to' must be a block height (integer)`);
}
if (from > to) {
return res.status(400).send(`Parameter 'to' must be a higher block height than 'from'`);
}
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
res.json(await blocks.$getBlocksByBulk(from, to));
} catch (e) {
res.status(500).send(e instanceof Error ? e.message : e);
}
}
private async getLegacyBlocks(req: Request, res: Response) {
try {
const returnBlocks: IEsploraApi.Block[] = [];

View File

@ -688,7 +688,6 @@ class Blocks {
}
public async $getBlocks(fromHeight?: number, limit: number = 15): Promise<BlockExtended[]> {
let currentHeight = fromHeight !== undefined ? fromHeight : this.currentBlockHeight;
if (currentHeight > this.currentBlockHeight) {
limit -= currentHeight - this.currentBlockHeight;
@ -728,6 +727,63 @@ class Blocks {
return returnBlocks;
}
public async $getBlocksByBulk(start: number, end: number) {
start = Math.max(1, start);
const blocks: any[] = [];
for (let i = end; i >= start; --i) {
const blockHash = await bitcoinApi.$getBlockHash(i);
const coreBlock = await bitcoinClient.getBlock(blockHash);
const electrsBlock = await bitcoinApi.$getBlock(blockHash);
const txs = await this.$getTransactionsExtended(blockHash, i, true);
const stats = await bitcoinClient.getBlockStats(blockHash);
const header = await bitcoinClient.getBlockHeader(blockHash, false);
const txoutset = await bitcoinClient.getTxoutSetinfo('none', i);
const formatted = {
blockhash: coreBlock.id,
blockheight: coreBlock.height,
prev_blockhash: coreBlock.previousblockhash,
timestamp: coreBlock.timestamp,
median_timestamp: coreBlock.mediantime,
// @ts-ignore
blocktime: coreBlock.time,
orphaned: null,
header: header,
version: coreBlock.version,
difficulty: coreBlock.difficulty,
merkle_root: coreBlock.merkle_root,
bits: coreBlock.bits,
nonce: coreBlock.nonce,
coinbase_scriptsig: txs[0].vin[0].scriptsig,
coinbase_address: txs[0].vout[0].scriptpubkey_address,
coinbase_signature: txs[0].vout[0].scriptpubkey_asm,
size: coreBlock.size,
virtual_size: coreBlock.weight / 4.0,
weight: coreBlock.weight,
utxoset_size: txoutset.txouts,
utxoset_change: stats.utxo_increase,
total_txs: coreBlock.tx_count,
avg_tx_size: Math.round(stats.total_size / stats.txs * 100) * 0.01,
total_inputs: stats.ins,
total_outputs: stats.outs,
total_input_amt: Math.round(txoutset.block_info.prevout_spent * 100000000),
total_output_amt: stats.total_out,
block_subsidy: txs[0].vout.reduce((acc, curr) => acc + curr.value, 0),
total_fee: stats.totalfee,
avg_feerate: stats.avgfeerate,
feerate_percentiles: [stats.minfeerate, stats.feerate_percentiles, stats.maxfeerate].flat(),
avg_fee: stats.avgfee,
fee_percentiles: null,
segwit_total_txs: stats.swtxs,
segwit_total_size: stats.swtotal_size,
segwit_total_weight: stats.swtotal_weight,
};
blocks.push(formatted);
}
return blocks;
}
public async $getBlockAuditSummary(hash: string): Promise<any> {
let summary;
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) {

View File

@ -88,5 +88,6 @@ module.exports = {
verifyTxOutProof: 'verifytxoutproof', // bitcoind v0.11.0+
walletLock: 'walletlock',
walletPassphrase: 'walletpassphrase',
walletPassphraseChange: 'walletpassphrasechange'
walletPassphraseChange: 'walletpassphrasechange',
getTxoutSetinfo: 'gettxoutsetinfo'
}