From 352ea950a29de6e24d2a560c28b8391f05457265 Mon Sep 17 00:00:00 2001 From: nymkappa Date: Fri, 25 Mar 2022 14:22:22 +0900 Subject: [PATCH] Use mining pool slug in urls --- backend/src/api/blocks.ts | 3 ++- backend/src/api/mining.ts | 11 +++++---- backend/src/index.ts | 10 ++++---- backend/src/mempool.interfaces.ts | 3 +++ backend/src/repositories/BlocksRepository.ts | 12 +++++++--- .../src/repositories/HashratesRepository.ts | 14 +++++++---- backend/src/repositories/PoolsRepository.ts | 17 ++++++------- backend/src/routes.ts | 6 ++--- backend/src/utils/blocks-utils.ts | 1 + frontend/src/app/app-routing.module.ts | 6 ++--- .../blockchain-blocks.component.html | 2 +- .../blocks-list/blocks-list.component.html | 2 +- .../pool-ranking/pool-ranking.component.html | 2 +- .../pool-ranking/pool-ranking.component.ts | 2 +- .../src/app/components/pool/pool.component.ts | 24 +++++++++---------- .../app/dashboard/dashboard.component.html | 2 +- .../src/app/interfaces/node-api.interface.ts | 2 ++ frontend/src/app/services/api.service.ts | 12 +++++----- 18 files changed, 76 insertions(+), 55 deletions(-) diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index bff73dd54..80e7a4e1f 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -137,7 +137,8 @@ class Blocks { } blockExtended.extras.pool = { id: pool.id, - name: pool.name + name: pool.name, + slug: pool.slug, }; } diff --git a/backend/src/api/mining.ts b/backend/src/api/mining.ts index 35884efb3..7e15c85d0 100644 --- a/backend/src/api/mining.ts +++ b/backend/src/api/mining.ts @@ -33,7 +33,8 @@ class Mining { link: poolInfo.link, blockCount: poolInfo.blockCount, rank: rank++, - emptyBlocks: emptyBlocksCount.length > 0 ? emptyBlocksCount[0]['count'] : 0 + emptyBlocks: emptyBlocksCount.length > 0 ? emptyBlocksCount[0]['count'] : 0, + slug: poolInfo.slug, }; poolsStats.push(poolStat); }); @@ -54,14 +55,14 @@ class Mining { /** * Get all mining pool stats for a pool */ - public async $getPoolStat(poolId: number): Promise { - const pool = await PoolsRepository.$getPool(poolId); + public async $getPoolStat(slug: string): Promise { + const pool = await PoolsRepository.$getPool(slug); if (!pool) { throw new Error(`This mining pool does not exist`); } - const blockCount: number = await BlocksRepository.$blockCount(poolId); - const emptyBlocksCount = await BlocksRepository.$countEmptyBlocks(poolId); + const blockCount: number = await BlocksRepository.$blockCount(pool.id); + const emptyBlocksCount = await BlocksRepository.$countEmptyBlocks(pool.id); return { pool: pool, diff --git a/backend/src/index.ts b/backend/src/index.ts index d5bf0e59e..62f9a8cd9 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -301,11 +301,11 @@ class Server { .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/2y', routes.$getPools.bind(routes, '2y')) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3y', routes.$getPools.bind(routes, '3y')) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/all', routes.$getPools.bind(routes, 'all')) - .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId/hashrate', routes.$getPoolHistoricalHashrate) - .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId/blocks', routes.$getPoolBlocks) - .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId/blocks/:height', routes.$getPoolBlocks) - .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId', routes.$getPool) - .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId/:interval', routes.$getPool) + .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/hashrate', routes.$getPoolHistoricalHashrate) + .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/blocks', routes.$getPoolBlocks) + .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/blocks/:height', routes.$getPoolBlocks) + .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug', routes.$getPool) + .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/:interval', routes.$getPool) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty', routes.$getHistoricalDifficulty) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty/:interval', routes.$getHistoricalDifficulty) .get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools', routes.$getPoolsHistoricalHashrate) diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index 15d1ad618..0081bd34f 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -6,6 +6,7 @@ export interface PoolTag { link: string; regexes: string; // JSON array addresses: string; // JSON array + slug: string; } export interface PoolInfo { @@ -13,6 +14,7 @@ export interface PoolInfo { name: string; link: string; blockCount: number; + slug: string; } export interface PoolStats extends PoolInfo { @@ -87,6 +89,7 @@ export interface BlockExtension { pool?: { id: number; name: string; + slug: string; }; avgFee?: number; avgFeeRate?: number; diff --git a/backend/src/repositories/BlocksRepository.ts b/backend/src/repositories/BlocksRepository.ts index 33cb727d9..5b253d3a0 100644 --- a/backend/src/repositories/BlocksRepository.ts +++ b/backend/src/repositories/BlocksRepository.ts @@ -3,6 +3,7 @@ import { DB } from '../database'; import logger from '../logger'; import { Common } from '../api/common'; import { prepareBlock } from '../utils/blocks-utils'; +import PoolsRepository from './PoolsRepository'; class BlocksRepository { /** @@ -235,13 +236,18 @@ class BlocksRepository { /** * Get blocks mined by a specific mining pool */ - public async $getBlocksByPool(poolId: number, startHeight: number | undefined = undefined): Promise { + public async $getBlocksByPool(slug: string, startHeight: number | undefined = undefined): Promise { + const pool = await PoolsRepository.$getPool(slug); + if (!pool) { + throw new Error(`This mining pool does not exist`); + } + const params: any[] = []; let query = ` SELECT *, UNIX_TIMESTAMP(blocks.blockTimestamp) as blockTimestamp, previous_block_hash as previousblockhash FROM blocks WHERE pool_id = ?`; - params.push(poolId); + params.push(pool.id); if (startHeight !== undefined) { query += ` AND height < ?`; @@ -277,7 +283,7 @@ class BlocksRepository { try { const [rows]: any[] = await connection.query(` SELECT *, UNIX_TIMESTAMP(blocks.blockTimestamp) as blockTimestamp, - pools.id as pool_id, pools.name as pool_name, pools.link as pool_link, + pools.id as pool_id, pools.name as pool_name, pools.link as pool_link, pools.slug as pool_slug, pools.addresses as pool_addresses, pools.regexes as pool_regexes, previous_block_hash as previousblockhash FROM blocks diff --git a/backend/src/repositories/HashratesRepository.ts b/backend/src/repositories/HashratesRepository.ts index 5237e6cb7..5efce29fe 100644 --- a/backend/src/repositories/HashratesRepository.ts +++ b/backend/src/repositories/HashratesRepository.ts @@ -120,8 +120,11 @@ class HashratesRepository { /** * Returns a pool hashrate history */ - public async $getPoolWeeklyHashrate(poolId: number): Promise { - const connection = await DB.getConnection(); + public async $getPoolWeeklyHashrate(slug: string): Promise { + const pool = await PoolsRepository.$getPool(slug); + if (!pool) { + throw new Error(`This mining pool does not exist`); + } // Find hashrate boundaries let query = `SELECT MIN(hashrate_timestamp) as firstTimestamp, MAX(hashrate_timestamp) as lastTimestamp @@ -134,8 +137,11 @@ class HashratesRepository { firstTimestamp: '1970-01-01', lastTimestamp: '9999-01-01' }; + + let connection; try { - const [rows]: any[] = await connection.query(query, [poolId]); + connection = await DB.getConnection(); + const [rows]: any[] = await connection.query(query, [pool.id]); boundaries = rows[0]; connection.release(); } catch (e) { @@ -152,7 +158,7 @@ class HashratesRepository { ORDER by hashrate_timestamp`; try { - const [rows]: any[] = await connection.query(query, [boundaries.firstTimestamp, boundaries.lastTimestamp, poolId]); + const [rows]: any[] = await connection.query(query, [boundaries.firstTimestamp, boundaries.lastTimestamp, pool.id]); connection.release(); return rows; diff --git a/backend/src/repositories/PoolsRepository.ts b/backend/src/repositories/PoolsRepository.ts index 4c3fd67ce..d9defaaed 100644 --- a/backend/src/repositories/PoolsRepository.ts +++ b/backend/src/repositories/PoolsRepository.ts @@ -9,7 +9,7 @@ class PoolsRepository { */ public async $getPools(): Promise { const connection = await DB.getConnection(); - const [rows] = await connection.query('SELECT id, name, addresses, regexes FROM pools;'); + const [rows] = await connection.query('SELECT id, name, addresses, regexes, slug FROM pools;'); connection.release(); return rows; } @@ -19,7 +19,7 @@ class PoolsRepository { */ public async $getUnknownPool(): Promise { const connection = await DB.getConnection(); - const [rows] = await connection.query('SELECT id, name FROM pools where name = "Unknown"'); + const [rows] = await connection.query('SELECT id, name, slug FROM pools where name = "Unknown"'); connection.release(); return rows[0]; } @@ -30,7 +30,7 @@ class PoolsRepository { public async $getPoolsInfo(interval: string | null = null): Promise { interval = Common.getSqlInterval(interval); - let query = `SELECT COUNT(height) as blockCount, pool_id as poolId, pools.name as name, pools.link as link + let query = `SELECT COUNT(height) as blockCount, pool_id as poolId, pools.name as name, pools.link as link, slug FROM blocks JOIN pools on pools.id = pool_id`; @@ -80,16 +80,17 @@ class PoolsRepository { /** * Get mining pool statistics for one pool */ - public async $getPool(poolId: any): Promise { + public async $getPool(slug: string): Promise { const query = ` SELECT * FROM pools - WHERE pools.id = ?`; + WHERE pools.slug = ?`; - // logger.debug(query); - const connection = await DB.getConnection(); + let connection; try { - const [rows] = await connection.query(query, [poolId]); + connection = await DB.getConnection(); + + const [rows] = await connection.query(query, [slug]); connection.release(); rows[0].regexes = JSON.parse(rows[0].regexes); diff --git a/backend/src/routes.ts b/backend/src/routes.ts index b14ea6ac4..e98c718ef 100644 --- a/backend/src/routes.ts +++ b/backend/src/routes.ts @@ -539,7 +539,7 @@ class Routes { public async $getPool(req: Request, res: Response) { try { - const stats = await mining.$getPoolStat(parseInt(req.params.poolId, 10)); + const stats = await mining.$getPoolStat(req.params.slug); res.header('Pragma', 'public'); res.header('Cache-control', 'public'); res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); @@ -552,7 +552,7 @@ class Routes { public async $getPoolBlocks(req: Request, res: Response) { try { const poolBlocks = await BlocksRepository.$getBlocksByPool( - parseInt(req.params.poolId, 10), + req.params.slug, req.params.height === undefined ? undefined : parseInt(req.params.height, 10), ); res.header('Pragma', 'public'); @@ -606,7 +606,7 @@ class Routes { public async $getPoolHistoricalHashrate(req: Request, res: Response) { try { - const hashrates = await HashratesRepository.$getPoolWeeklyHashrate(parseInt(req.params.poolId, 10)); + const hashrates = await HashratesRepository.$getPoolWeeklyHashrate(req.params.slug); const oldestIndexedBlockTimestamp = await BlocksRepository.$oldestBlockTimestamp(); res.header('Pragma', 'public'); res.header('Cache-control', 'public'); diff --git a/backend/src/utils/blocks-utils.ts b/backend/src/utils/blocks-utils.ts index 107099ba3..7b5c0b23a 100644 --- a/backend/src/utils/blocks-utils.ts +++ b/backend/src/utils/blocks-utils.ts @@ -23,6 +23,7 @@ export function prepareBlock(block: any): BlockExtended { pool: block?.extras?.pool ?? (block?.pool_id ? { id: block.pool_id, name: block.pool_name, + slug: block.pool_slug, } : undefined), } }; diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index 003bbcf0d..d46da5696 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -85,7 +85,7 @@ let routes: Routes = [ path: 'pool', children: [ { - path: ':poolId', + path: ':slug', component: PoolComponent, }, ] @@ -227,7 +227,7 @@ let routes: Routes = [ path: 'pool', children: [ { - path: ':poolId', + path: ':slug', component: PoolComponent, }, ] @@ -363,7 +363,7 @@ let routes: Routes = [ path: 'pool', children: [ { - path: ':poolId', + path: ':slug', component: PoolComponent, }, ] diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html index bc0025d2b..d41d34b81 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html @@ -25,7 +25,7 @@
diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.html b/frontend/src/app/components/blocks-list/blocks-list.component.html index 22693a856..e7c93d3ab 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.html +++ b/frontend/src/app/components/blocks-list/blocks-list.component.html @@ -25,7 +25,7 @@
- + {{ block.extras.pool.name }} diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.html b/frontend/src/app/components/pool-ranking/pool-ranking.component.html index 15eed9f22..521f60d81 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.html +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.html @@ -85,7 +85,7 @@ {{ pool.rank }} - {{ pool.name }} + {{ pool.name }} {{ pool.lastEstimatedHashrate }} {{ miningStats.miningUnits.hashrateUnit }} {{ pool['blockText'] }} diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts index 0722466fc..95156a487 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts @@ -159,7 +159,7 @@ export class PoolRankingComponent implements OnInit { } } }, - data: pool.poolId, + data: pool.slug, } as PieSeriesOption); }); diff --git a/frontend/src/app/components/pool/pool.component.ts b/frontend/src/app/components/pool/pool.component.ts index dee4a9713..82669ad26 100644 --- a/frontend/src/app/components/pool/pool.component.ts +++ b/frontend/src/app/components/pool/pool.component.ts @@ -32,9 +32,9 @@ export class PoolComponent implements OnInit { }; blocks: BlockExtended[] = []; - poolId: number = undefined; + slug: string = undefined; - loadMoreSubject: BehaviorSubject = new BehaviorSubject(this.poolId); + loadMoreSubject: BehaviorSubject = new BehaviorSubject(this.slug); constructor( @Inject(LOCALE_ID) public locale: string, @@ -45,23 +45,23 @@ export class PoolComponent implements OnInit { } ngOnInit(): void { - this.poolStats$ = this.route.params.pipe(map((params) => params.poolId)) + this.poolStats$ = this.route.params.pipe(map((params) => params.slug)) .pipe( - switchMap((poolId: any) => { + switchMap((slug: any) => { this.isLoading = true; - this.poolId = poolId; - this.loadMoreSubject.next(this.poolId); - return this.apiService.getPoolHashrate$(this.poolId) + this.slug = slug; + this.loadMoreSubject.next(this.slug); + return this.apiService.getPoolHashrate$(this.slug) .pipe( switchMap((data) => { this.isLoading = false; this.prepareChartOptions(data.hashrates.map(val => [val.timestamp * 1000, val.avgHashrate])); - return poolId; + return slug; }), ); }), switchMap(() => { - return this.apiService.getPoolStats$(this.poolId); + return this.apiService.getPoolStats$(this.slug); }), map((poolStats) => { let regexes = '"'; @@ -80,10 +80,10 @@ export class PoolComponent implements OnInit { this.blocks$ = this.loadMoreSubject .pipe( switchMap((flag) => { - if (this.poolId === undefined) { + if (this.slug === undefined) { return []; } - return this.apiService.getPoolBlocks$(this.poolId, this.blocks[this.blocks.length - 1]?.height); + return this.apiService.getPoolBlocks$(this.slug, this.blocks[this.blocks.length - 1]?.height); }), tap((newBlocks) => { this.blocks = this.blocks.concat(newBlocks); @@ -182,7 +182,7 @@ export class PoolComponent implements OnInit { } loadMore() { - this.loadMoreSubject.next(this.poolId); + this.loadMoreSubject.next(this.slug); } trackByBlock(index: number, block: BlockExtended) { diff --git a/frontend/src/app/dashboard/dashboard.component.html b/frontend/src/app/dashboard/dashboard.component.html index 3a028adc8..95ff4aa33 100644 --- a/frontend/src/app/dashboard/dashboard.component.html +++ b/frontend/src/app/dashboard/dashboard.component.html @@ -120,7 +120,7 @@ {{ block.height }} - + {{ block.extras.pool.name }} diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts index 786fd6687..022e215d0 100644 --- a/frontend/src/app/interfaces/node-api.interface.ts +++ b/frontend/src/app/interfaces/node-api.interface.ts @@ -71,6 +71,7 @@ export interface SinglePoolStats { lastEstimatedHashrate: string; emptyBlockRatio: string; logo: string; + slug: string; } export interface PoolsStats { blockCount: number; @@ -107,6 +108,7 @@ export interface BlockExtension { pool?: { id: number; name: string; + slug: string; } stage?: number; // Frontend only diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts index 92068c44e..7be8b944f 100644 --- a/frontend/src/app/services/api.service.ts +++ b/frontend/src/app/services/api.service.ts @@ -132,17 +132,17 @@ export class ApiService { ); } - getPoolStats$(poolId: number): Observable { - return this.httpClient.get(this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/pool/${poolId}`); + getPoolStats$(slug: string): Observable { + return this.httpClient.get(this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/pool/${slug}`); } - getPoolHashrate$(poolId: number): Observable { - return this.httpClient.get(this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/pool/${poolId}/hashrate`); + getPoolHashrate$(slug: string): Observable { + return this.httpClient.get(this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/pool/${slug}/hashrate`); } - getPoolBlocks$(poolId: number, fromHeight: number): Observable { + getPoolBlocks$(slug: string, fromHeight: number): Observable { return this.httpClient.get( - this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/pool/${poolId}/blocks` + + this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/pool/${slug}/blocks` + (fromHeight !== undefined ? `/${fromHeight}` : '') ); }