From 0ebe0a5dc9985866c1c2efb2a5455fac5d6dffef Mon Sep 17 00:00:00 2001 From: nymkappa <1612910616@pm.me> Date: Thu, 16 Mar 2023 16:13:11 +0900 Subject: [PATCH 1/3] Add new stats in mining pool page --- backend/src/api/mining/mining.ts | 6 + backend/src/repositories/BlocksRepository.ts | 49 ++++++++ .../components/pool/pool-preview.component.ts | 5 - .../app/components/pool/pool.component.html | 106 ++++++++++-------- .../app/components/pool/pool.component.scss | 13 ++- .../src/app/components/pool/pool.component.ts | 10 +- .../src/app/interfaces/node-api.interface.ts | 4 +- 7 files changed, 128 insertions(+), 65 deletions(-) diff --git a/backend/src/api/mining/mining.ts b/backend/src/api/mining/mining.ts index 8b4abb0d6..58626df65 100644 --- a/backend/src/api/mining/mining.ts +++ b/backend/src/api/mining/mining.ts @@ -13,6 +13,7 @@ import BlocksAuditsRepository from '../../repositories/BlocksAuditsRepository'; import PricesRepository from '../../repositories/PricesRepository'; import { bitcoinCoreApi } from '../bitcoin/bitcoin-api-factory'; import { IEsploraApi } from '../bitcoin/esplora-api.interface'; +import database from '../../database'; class Mining { private blocksPriceIndexingRunning = false; @@ -141,6 +142,9 @@ class Mining { const blockCount1w: number = await BlocksRepository.$blockCount(pool.id, '1w'); const totalBlock1w: number = await BlocksRepository.$blockCount(null, '1w'); + const avgHealth = await BlocksRepository.$getAvgBlockHealthPerPoolId(pool.id); + const totalReward = await BlocksRepository.$getTotalRewardForPoolId(pool.id); + let currentEstimatedHashrate = 0; try { currentEstimatedHashrate = await bitcoinClient.getNetworkHashPs(totalBlock24h); @@ -162,6 +166,8 @@ class Mining { }, estimatedHashrate: currentEstimatedHashrate * (blockCount24h / totalBlock24h), reportedHashrate: null, + avgBlockHealth: avgHealth, + totalReward: totalReward, }; } diff --git a/backend/src/repositories/BlocksRepository.ts b/backend/src/repositories/BlocksRepository.ts index f2d0a283e..04dcd4b56 100644 --- a/backend/src/repositories/BlocksRepository.ts +++ b/backend/src/repositories/BlocksRepository.ts @@ -330,6 +330,55 @@ class BlocksRepository { } } + /** + * Get average block health for all blocks for a single pool + */ + public async $getAvgBlockHealthPerPoolId(poolId: number): Promise { + const params: any[] = []; + const query = ` + SELECT AVG(blocks_audits.match_rate) AS avg_match_rate + FROM blocks + JOIN blocks_audits ON blocks.height = blocks_audits.height + WHERE blocks.pool_id = ? + `; + params.push(poolId); + + try { + const [rows] = await DB.query(query, params); + if (!rows[0] || !rows[0].avg_match_rate) { + return 0; + } + return Math.round(rows[0].avg_match_rate * 100) / 100; + } catch (e) { + logger.err(`Cannot get average block health for pool id ${poolId}. Reason: ` + (e instanceof Error ? e.message : e)); + throw e; + } + } + + /** + * Get average block health for all blocks for a single pool + */ + public async $getTotalRewardForPoolId(poolId: number): Promise { + const params: any[] = []; + const query = ` + SELECT sum(reward) as total_reward + FROM blocks + WHERE blocks.pool_id = ? + `; + params.push(poolId); + + try { + const [rows] = await DB.query(query, params); + if (!rows[0] || !rows[0].total_reward) { + return 0; + } + return rows[0].total_reward; + } catch (e) { + logger.err(`Cannot get total reward for pool id ${poolId}. Reason: ` + (e instanceof Error ? e.message : e)); + throw e; + } + } + /** * Get the oldest indexed block */ diff --git a/frontend/src/app/components/pool/pool-preview.component.ts b/frontend/src/app/components/pool/pool-preview.component.ts index 277bacb33..0431686d6 100644 --- a/frontend/src/app/components/pool/pool-preview.component.ts +++ b/frontend/src/app/components/pool/pool-preview.component.ts @@ -86,11 +86,6 @@ export class PoolPreviewComponent implements OnInit { regexes += regex + '", "'; } poolStats.pool.regexes = regexes.slice(0, -3); - poolStats.pool.addresses = poolStats.pool.addresses; - - if (poolStats.reportedHashrate) { - poolStats.luck = poolStats.estimatedHashrate / poolStats.reportedHashrate * 100; - } this.openGraphService.waitOver('pool-stats-' + this.slug); diff --git a/frontend/src/app/components/pool/pool.component.html b/frontend/src/app/components/pool/pool.component.html index 0ae32ccb8..d7c791db9 100644 --- a/frontend/src/app/components/pool/pool.component.html +++ b/frontend/src/app/components/pool/pool.component.html @@ -37,13 +37,13 @@ Addresses - - + + {{ poolStats.pool.addresses[0] }}
- {{ address }}
@@ -67,13 +67,13 @@ [attr.aria-expanded]="!gfg" aria-controls="collapseExample"> Show all ({{ poolStats.pool.addresses.length }}) - - {{ poolStats.pool.addresses[0] | shortenString: 40 }} + + {{ poolStats.pool.addresses[0] | shortenString: 30 }}
- {{ - address | shortenString: 40 }}
+ address | shortenString: 30 }}
@@ -88,22 +88,25 @@ - Hashrate (24h) - - - + + + - - - - - + + +
EstimatedReportedLuckRewardHashrate (24h)Avg Health
{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}{{ poolStats.reportedHashrate | amountShortener : 1 : 'H/s' }}{{ formatNumber(poolStats.luck, this.locale, '1.2-2') }}%{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}{{ poolStats.avgBlockHealth }}% + + Unknown + +
@@ -111,49 +114,46 @@ - Hashrate (24h) - - - + + + - - - - - + + +
EstimatedReportedLuckRewardHashrate (24h)Avg Health
{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}{{ poolStats.reportedHashrate | amountShortener : 1 : 'H/s' }}{{ formatNumber(poolStats.luck, this.locale, '1.2-2') }}%{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}{{ poolStats.avgBlockHealth }}% + + Unknown + +
- - ~ - ~ - - - Mined blocks - - - + + + - - -
24h1wAllBlocks 24h1wAll
{{ formatNumber(poolStats.blockCount['24h'], this.locale, '1.0-0') }} ({{ formatNumber(100 * + {{ formatNumber(poolStats.blockCount['24h'], this.locale, '1.0-0') }} ({{ formatNumber(100 * poolStats.blockShare['24h'], this.locale, '1.0-0') }}%){{ formatNumber(poolStats.blockCount['1w'], this.locale, '1.0-0') }} ({{ formatNumber(100 * + {{ formatNumber(poolStats.blockCount['1w'], this.locale, '1.0-0') }} ({{ formatNumber(100 * poolStats.blockShare['1w'], this.locale, '1.0-0') }}%){{ formatNumber(poolStats.blockCount['all'], this.locale, '1.0-0') }} ({{ formatNumber(100 * + {{ formatNumber(poolStats.blockCount['all'], this.locale, '1.0-0') }} ({{ formatNumber(100 * poolStats.blockShare['all'], this.locale, '1.0-0') }}%)
@@ -162,21 +162,20 @@ - Mined blocks - - - + + + - - -
24h1wAllBlocks 24h1wAll
{{ formatNumber(poolStats.blockCount['24h'], this.locale, '1.0-0') }} ({{ formatNumber(100 * + {{ formatNumber(poolStats.blockCount['24h'], this.locale, '1.0-0') }} ({{ formatNumber(100 * poolStats.blockShare['24h'], this.locale, '1.0-0') }}%){{ formatNumber(poolStats.blockCount['1w'], this.locale, '1.0-0') }} ({{ formatNumber(100 * + {{ formatNumber(poolStats.blockCount['1w'], this.locale, '1.0-0') }} ({{ formatNumber(100 * poolStats.blockShare['1w'], this.locale, '1.0-0') }}%){{ formatNumber(poolStats.blockCount['all'], this.locale, '1.0-0') }} ({{ formatNumber(100 * + {{ formatNumber(poolStats.blockCount['all'], this.locale, '1.0-0') }} ({{ formatNumber(100 * poolStats.blockShare['all'], this.locale, '1.0-0') }}%)
@@ -213,8 +212,9 @@ Timestamp Mined Coinbase tag + Health Reward - Fees + Fees TXs Size @@ -234,10 +234,24 @@ {{ block.extras.coinbaseRaw | hex2ascii }} + + {{ block.extras.matchRate }}% + + Unknown + + - + diff --git a/frontend/src/app/components/pool/pool.component.scss b/frontend/src/app/components/pool/pool.component.scss index 9103f38f5..21468773f 100644 --- a/frontend/src/app/components/pool/pool.component.scss +++ b/frontend/src/app/components/pool/pool.component.scss @@ -68,6 +68,11 @@ div.scrollable { vertical-align: top; padding-top: 25px; } +.addresses-data { + vertical-align: top; + font-family: monospace; + font-size: 14px; +} .data { text-align: right; @@ -100,7 +105,7 @@ div.scrollable { @media (max-width: 875px) { padding-left: 50px; } - @media (max-width: 650px) { + @media (max-width: 685px) { display: none; } } @@ -118,7 +123,7 @@ div.scrollable { padding-right: 10px; } @media (max-width: 875px) { - padding-right: 50px; + padding-right: 20px; } @media (max-width: 567px) { padding-right: 10px; @@ -186,10 +191,6 @@ div.scrollable { .block-count-title { color: #4a68b9; font-size: 14px; - text-align: left; - @media (max-width: 767.98px) { - text-align: center; - } } .table-data tr { diff --git a/frontend/src/app/components/pool/pool.component.ts b/frontend/src/app/components/pool/pool.component.ts index 56b8bd392..85fd028ef 100644 --- a/frontend/src/app/components/pool/pool.component.ts +++ b/frontend/src/app/components/pool/pool.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { EChartsOption, graphic } from 'echarts'; -import { BehaviorSubject, Observable, timer } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; import { distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators'; import { BlockExtended, PoolStat } from '../../interfaces/node-api.interface'; import { ApiService } from '../../services/api.service'; @@ -35,6 +35,8 @@ export class PoolComponent implements OnInit { blocks: BlockExtended[] = []; slug: string = undefined; + auditAvailable = false; + loadMoreSubject: BehaviorSubject = new BehaviorSubject(this.blocks[this.blocks.length - 1]?.height); constructor( @@ -44,6 +46,7 @@ export class PoolComponent implements OnInit { public stateService: StateService, private seoService: SeoService, ) { + this.auditAvailable = this.stateService.env.AUDIT; } ngOnInit(): void { @@ -74,11 +77,6 @@ export class PoolComponent implements OnInit { regexes += regex + '", "'; } poolStats.pool.regexes = regexes.slice(0, -3); - poolStats.pool.addresses = poolStats.pool.addresses; - - if (poolStats.reportedHashrate) { - poolStats.luck = poolStats.estimatedHashrate / poolStats.reportedHashrate * 100; - } return Object.assign({ logo: `/resources/mining-pools/` + poolStats.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg' diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts index cad623f9f..8d8f30863 100644 --- a/frontend/src/app/interfaces/node-api.interface.ts +++ b/frontend/src/app/interfaces/node-api.interface.ts @@ -107,8 +107,8 @@ export interface PoolStat { '1w': number, }; estimatedHashrate: number; - reportedHashrate: number; - luck?: number; + avgBlockHealth: number; + totalReward: number; } export interface BlockExtension { From 4a64c0dfa509078409e828dafab000cf4462382f Mon Sep 17 00:00:00 2001 From: nymkappa <1612910616@pm.me> Date: Thu, 16 Mar 2023 16:35:59 +0900 Subject: [PATCH 2/3] Fix skeleton --- .../app/components/pool/pool.component.html | 54 +++++++++---------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/frontend/src/app/components/pool/pool.component.html b/frontend/src/app/components/pool/pool.component.html index d7c791db9..aa54b70f5 100644 --- a/frontend/src/app/components/pool/pool.component.html +++ b/frontend/src/app/components/pool/pool.component.html @@ -37,7 +37,7 @@ Addresses - + {{ poolStats.pool.addresses[0] }} @@ -378,24 +378,23 @@ - Hashrate (24h) - - - + + + - - - @@ -405,23 +404,22 @@
EstimatedReportedLuckRewardHashrate (24h)Avg Health
+
+
+
- Hashrate (24h) - - - + + + - - - @@ -431,24 +429,23 @@ -
EstimatedReportedLuckRewardHashrate (24h)Avg Health
+
+
+
Mined blocks - - - + + + - - - @@ -458,23 +455,22 @@
24h1wAllBlocks 24h1wAll
+
+
+
- Mined blocks - - - + + + - - - From adc51f621743523503be04b66a9997750d7ee048 Mon Sep 17 00:00:00 2001 From: nymkappa <1612910616@pm.me> Date: Sat, 18 Mar 2023 16:40:30 +0900 Subject: [PATCH 3/3] Update i18n --- frontend/src/app/components/pool/pool.component.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/components/pool/pool.component.html b/frontend/src/app/components/pool/pool.component.html index aa54b70f5..57d7ac51c 100644 --- a/frontend/src/app/components/pool/pool.component.html +++ b/frontend/src/app/components/pool/pool.component.html @@ -92,9 +92,9 @@
24h1wAllBlocks 24h1wAll
+
+
+
- - - + + + @@ -117,9 +117,9 @@
RewardHashrate (24h)Avg HealthRewardHashrate (24h)Avg Health
- - - + + +
RewardHashrate (24h)Avg HealthRewardHashrate (24h)Avg Health