Generate mining basic pool ranking (sorted by block found) for a specified timeframe

This commit is contained in:
nymkappa
2022-01-06 19:59:33 +09:00
parent 4646cc6df3
commit 5ca98af7d1
16 changed files with 366 additions and 48 deletions

View File

@@ -1,16 +1,15 @@
import { IEsploraApi } from "../api/bitcoin/esplora-api.interface";
import { BlockExtended, PoolTag } from "../mempool.interfaces";
import { DB } from "../database";
import logger from "../logger";
import bitcoinApi from '../api/bitcoin/bitcoin-api-factory';
export interface EmptyBlocks {
emptyBlocks: number,
poolId: number,
}
class BlocksRepository {
/**
* Save indexed block data in the database
* @param block
* @param blockHash
* @param coinbaseTxid
* @param poolTag
*/
public async $saveBlockInDatabase(
block: BlockExtended,
@@ -26,7 +25,7 @@ class BlocksRepository {
weight, tx_count, coinbase_raw, difficulty,
pool_id, fees, fee_span, median_fee
) VALUE (
?, ?, ?, ?,
?, ?, FROM_UNIXTIME(?), ?,
?, ?, ?, ?,
?, ?, ?, ?
)`;
@@ -49,25 +48,49 @@ class BlocksRepository {
/**
* Check if a block has already been indexed in the database. Query the databse directly.
* This can be cached/optimized if required later on to avoid too many db queries.
* @param blockHeight
* @returns
*/
public async $isBlockAlreadyIndexed(blockHeight: number) {
const connection = await DB.pool.getConnection();
let exists = false;
try {
const query = `SELECT height from blocks where blocks.height = ${blockHeight}`;
const [rows]: any[] = await connection.query(query);
exists = rows.length === 1;
} catch (e) {
console.log(e);
logger.err('$isBlockAlreadyIndexed() error' + (e instanceof Error ? e.message : e));
}
const query = `SELECT height from blocks where blocks.height = ${blockHeight}`;
const [rows]: any[] = await connection.query(query);
exists = rows.length === 1;
connection.release();
return exists;
}
/**
* Count empty blocks for all pools
*/
public async $countEmptyBlocks(interval: string = "100 YEAR") : Promise<EmptyBlocks[]> {
const connection = await DB.pool.getConnection();
const [rows] = await connection.query(`
SELECT pool_id as poolId
FROM blocks
WHERE timestamp BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()
AND tx_count = 1;
`);
connection.release();
return <EmptyBlocks[]>rows;
}
/**
* Get blocks count for a period
*/
public async $blockCount(interval: string = "100 YEAR") : Promise<number> {
const connection = await DB.pool.getConnection();
const [rows] = await connection.query(`
SELECT count(height) as blockCount
FROM blocks
WHERE timestamp BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW();
`);
connection.release();
return <number>rows[0].blockCount;
}
}
export default new BlocksRepository();

View File

@@ -1,30 +1,43 @@
import { FieldPacket } from "mysql2";
import { DB } from "../database";
import { PoolTag } from "../mempool.interfaces"
import { PoolInfo, PoolTag } from "../mempool.interfaces"
class PoolsRepository {
/**
* Get all pools tagging info
*/
public async $getPools() : Promise<PoolTag[]> {
public async $getPools(): Promise<PoolTag[]> {
const connection = await DB.pool.getConnection();
const [rows]: [PoolTag[], FieldPacket[]] = await connection.query("SELECT * FROM pools;");
const [rows] = await connection.query("SELECT * FROM pools;");
connection.release();
return rows;
return <PoolTag[]>rows;
}
/**
* Get unknown pool tagging info
*/
public getUnknownPool(): PoolTag {
return <PoolTag>{
id: null,
name: 'Unknown',
link: 'rickroll?',
regexes: "[]",
addresses: "[]",
};
}
public async $getUnknownPool(): Promise<PoolTag> {
const connection = await DB.pool.getConnection();
const [rows] = await connection.query("SELECT * FROM pools where name = 'Unknown'");
connection.release();
return <PoolTag>rows[0];
}
/**
* Get basic pool info and block count
*/
public async $getPoolsInfo(interval: string = "100 YEARS"): Promise<PoolInfo[]> {
const connection = await DB.pool.getConnection();
const [rows] = await connection.query(`
SELECT COUNT(height) as blockCount, pool_id as poolId, pools.name as name, pools.link as link
FROM blocks
JOIN pools on pools.id = pool_id
WHERE timestamp BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()
GROUP BY pool_id
ORDER BY COUNT(height) DESC;
`);
connection.release();
return <PoolInfo[]>rows;
}
}
export default new PoolsRepository();