diff --git a/backend/src/api/mining/mining.ts b/backend/src/api/mining/mining.ts index 83e810d43..edcb5b2e5 100644 --- a/backend/src/api/mining/mining.ts +++ b/backend/src/api/mining/mining.ts @@ -100,6 +100,7 @@ class Mining { rank: rank++, emptyBlocks: emptyBlocksCount.length > 0 ? emptyBlocksCount[0]['count'] : 0, slug: poolInfo.slug, + avgMatchRate: poolInfo.avgMatchRate !== null ? Math.round(100 * poolInfo.avgMatchRate) / 100 : null, }; poolsStats.push(poolStat); }); diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index f79786279..6b258c173 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -16,6 +16,7 @@ export interface PoolInfo { link: string; blockCount: number; slug: string; + avgMatchRate: number | null; } export interface PoolStats extends PoolInfo { diff --git a/backend/src/repositories/PoolsRepository.ts b/backend/src/repositories/PoolsRepository.ts index c7cc6cba3..56cc2b3bc 100644 --- a/backend/src/repositories/PoolsRepository.ts +++ b/backend/src/repositories/PoolsRepository.ts @@ -27,16 +27,25 @@ 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, slug + let query = ` + SELECT + COUNT(blocks.height) As blockCount, + pool_id AS poolId, + pools.name AS name, + pools.link AS link, + slug, + AVG(blocks_audits.match_rate) AS avgMatchRate FROM blocks - JOIN pools on pools.id = pool_id`; + JOIN pools on pools.id = pool_id + LEFT JOIN blocks_audits ON blocks_audits.height = blocks.height + `; if (interval) { query += ` WHERE blocks.blockTimestamp BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`; } query += ` GROUP BY pool_id - ORDER BY COUNT(height) DESC`; + ORDER BY COUNT(blocks.height) DESC`; try { const [rows] = await DB.query(query); 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 48f2407e8..35ab709c5 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.html +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.html @@ -92,6 +92,8 @@ Pool Hashrate Blocks + Avg Health Empty blocks @@ -104,7 +106,21 @@ {{ pool.name }} {{ pool.lastEstimatedHashrate }} {{ miningStats.miningUnits.hashrateUnit }} - {{ pool['blockText'] }} + + {{ pool.blockCount }} ({{ pool.share }}%) + + + {{ pool.avgMatchRate }}% + + Unknown + + {{ pool.emptyBlocks }} ({{ pool.emptyBlockRatio }}%) 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 214318bd5..ed27b6de7 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts @@ -26,6 +26,8 @@ export class PoolRankingComponent implements OnInit { miningWindowPreference: string; radioGroupForm: UntypedFormGroup; + auditAvailable = false; + indexingAvailable = false; isLoading = true; chartOptions: EChartsOption = {}; chartInitOptions = { @@ -60,6 +62,10 @@ export class PoolRankingComponent implements OnInit { this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference }); this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference); + this.indexingAvailable = (this.stateService.env.BASE_MODULE === 'mempool' && + this.stateService.env.MINING_DASHBOARD === true); + this.auditAvailable = this.indexingAvailable && this.stateService.env.AUDIT; + this.route .fragment .subscribe((fragment) => { @@ -92,7 +98,6 @@ export class PoolRankingComponent implements OnInit { ) .pipe( map(data => { - data.pools = data.pools.map((pool: SinglePoolStats) => this.formatPoolUI(pool)); data['minersLuck'] = (100 * (data.blockCount / 1008)).toFixed(2); // luck 1w return data; }), @@ -104,11 +109,6 @@ export class PoolRankingComponent implements OnInit { ); } - formatPoolUI(pool: SinglePoolStats) { - pool['blockText'] = pool.blockCount.toString() + ` (${pool.share}%)`; - return pool; - } - generatePoolsChartSerieData(miningStats) { let poolShareThreshold = 0.5; if (isMobile()) { diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts index c11cb5828..8fa30a723 100644 --- a/frontend/src/app/interfaces/node-api.interface.ts +++ b/frontend/src/app/interfaces/node-api.interface.ts @@ -73,6 +73,7 @@ export interface SinglePoolStats { emptyBlockRatio: string; logo: string; slug: string; + avgMatchRate: number; } export interface PoolsStats { blockCount: number;