From ec40231f930aeaf103a9c6818fae13adb194630b Mon Sep 17 00:00:00 2001 From: nymkappa Date: Thu, 24 Feb 2022 20:20:18 +0900 Subject: [PATCH] warn on re-index - fix hash indexing state issue - cleanup ui mining --- backend/src/api/database-migration.ts | 5 +++- backend/src/index.ts | 10 +++++-- .../src/repositories/HashratesRepository.ts | 5 ++-- .../hashrate-chart.component.ts | 5 +++- .../hashrate-chart-pools.component.html | 24 ----------------- .../hashrate-chart-pools.component.scss | 6 ++--- .../hashrate-chart-pools.component.ts | 26 +++++++++---------- .../mining-dashboard.component.html | 2 +- .../mining-dashboard.component.scss | 2 +- .../mining-dashboard.component.ts | 5 +++- .../pool-ranking/pool-ranking.component.ts | 8 +++--- 11 files changed, 45 insertions(+), 53 deletions(-) diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index 931c9ec6d..49e9ef9c4 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -92,11 +92,13 @@ class DatabaseMigration { await this.$executeQuery(connection, this.getCreateBlocksTableQuery(), await this.$checkIfTableExists('blocks')); } if (databaseSchemaVersion < 5 && isBitcoin === true) { + logger.warn(`'blocks' table has been truncated. Re-indexing from scratch.'`); await this.$executeQuery(connection, 'TRUNCATE blocks;'); // Need to re-index await this.$executeQuery(connection, 'ALTER TABLE blocks ADD `reward` double unsigned NOT NULL DEFAULT "0"'); } if (databaseSchemaVersion < 6 && isBitcoin === true) { + logger.warn(`'blocks' table has been truncated. Re-indexing from scratch.'`); await this.$executeQuery(connection, 'TRUNCATE blocks;'); // Need to re-index // Cleanup original blocks fields type await this.$executeQuery(connection, 'ALTER TABLE blocks MODIFY `height` integer unsigned NOT NULL DEFAULT "0"'); @@ -123,7 +125,8 @@ class DatabaseMigration { } if (databaseSchemaVersion < 8 && isBitcoin === true) { - await this.$executeQuery(connection, 'TRUNCATE hashrates;'); + logger.warn(`'hashrates' table has been truncated. Re-indexing from scratch.'`); + await this.$executeQuery(connection, 'TRUNCATE hashrates;'); // Need to re-index await this.$executeQuery(connection, 'ALTER TABLE `hashrates` DROP INDEX `PRIMARY`'); await this.$executeQuery(connection, 'ALTER TABLE `hashrates` ADD `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST'); await this.$executeQuery(connection, 'ALTER TABLE `hashrates` ADD `share` float NOT NULL DEFAULT "0"'); diff --git a/backend/src/index.ts b/backend/src/index.ts index 5702ee032..4305d6dac 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -27,6 +27,7 @@ import syncAssets from './sync-assets'; import icons from './api/liquid/icons'; import { Common } from './api/common'; import mining from './api/mining'; +import HashratesRepository from './repositories/HashratesRepository'; class Server { private wss: WebSocket.Server | undefined; @@ -95,6 +96,7 @@ class Server { await Common.sleep(5000); await databaseMigration.$truncateIndexedData(tables); } + await this.$resetHashratesIndexingState(); await databaseMigration.$initializeOrMigrateDatabase(); await poolsParser.migratePoolsJson(); } catch (e) { @@ -145,7 +147,7 @@ class Server { } await blocks.$updateBlocks(); await memPool.$updateMempool(); - this.runIndexingWhenReady(); + this.$runIndexingWhenReady(); setTimeout(this.runMainUpdateLoop.bind(this), config.MEMPOOL.POLL_RATE_MS); this.currentBackendRetryInterval = 5; @@ -164,7 +166,11 @@ class Server { } } - async runIndexingWhenReady() { + async $resetHashratesIndexingState() { + return await HashratesRepository.$setLatestRunTimestamp(0); + } + + async $runIndexingWhenReady() { if (!Common.indexingEnabled() || mempool.hasPriority()) { return; } diff --git a/backend/src/repositories/HashratesRepository.ts b/backend/src/repositories/HashratesRepository.ts index d11c444d5..6d49be811 100644 --- a/backend/src/repositories/HashratesRepository.ts +++ b/backend/src/repositories/HashratesRepository.ts @@ -84,10 +84,11 @@ class HashratesRepository { return rows; } - public async $setLatestRunTimestamp() { + public async $setLatestRunTimestamp(val: any = null) { const connection = await DB.pool.getConnection(); const query = `UPDATE state SET number = ? WHERE name = 'last_hashrates_indexing'`; - await connection.query(query, [Math.round(new Date().getTime() / 1000)]); + + await connection.query(query, (val === null) ? [Math.round(new Date().getTime() / 1000)] : [val]); connection.release(); } diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts index 961e4786e..37b4f07ba 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -45,12 +45,15 @@ export class HashrateChartComponent implements OnInit { private apiService: ApiService, private formBuilder: FormBuilder, ) { - this.seoService.setTitle($localize`:@@mining.hashrate-difficulty:Hashrate and Difficulty`); this.radioGroupForm = this.formBuilder.group({ dateSpan: '1y' }); this.radioGroupForm.controls.dateSpan.setValue('1y'); } ngOnInit(): void { + if (!this.widget) { + this.seoService.setTitle($localize`:@@mining.hashrate-difficulty:Hashrate and Difficulty`); + } + this.hashrateObservable$ = this.radioGroupForm.get('dateSpan').valueChanges .pipe( startWith('1y'), diff --git a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html index ea5c5a2a7..8750caa56 100644 --- a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html +++ b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html @@ -30,29 +30,5 @@
- - diff --git a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.scss b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.scss index 590de28db..316f0fc47 100644 --- a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.scss +++ b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.scss @@ -11,12 +11,12 @@ .full-container { width: 100%; - height: calc(100% - 50px); + height: calc(100% - 100px); @media (max-width: 992px) { - height: calc(100% - 110px); + height: calc(100% - 140px); }; @media (max-width: 576px) { - height: calc(100% - 130px); + height: calc(100% - 180px); }; } diff --git a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts index 9a9526f00..79ac7e2e1 100644 --- a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts +++ b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts @@ -1,10 +1,9 @@ -import { Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'; import { EChartsOption } from 'echarts'; import { Observable } from 'rxjs'; import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; import { ApiService } from 'src/app/services/api.service'; import { SeoService } from 'src/app/services/seo.service'; -import { formatNumber } from '@angular/common'; import { FormBuilder, FormGroup } from '@angular/forms'; import { poolsColor } from 'src/app/app.constants'; @@ -15,11 +14,12 @@ import { poolsColor } from 'src/app/app.constants'; styles: [` .loadingGraphs { position: absolute; - top: 38%; + top: 50%; left: calc(50% - 15px); z-index: 100; } `], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class HashrateChartPoolsComponent implements OnInit { @Input() widget: boolean = false; @@ -37,7 +37,6 @@ export class HashrateChartPoolsComponent implements OnInit { hashrateObservable$: Observable; isLoading = true; - formatNumber = formatNumber; constructor( @Inject(LOCALE_ID) public locale: string, @@ -45,19 +44,24 @@ export class HashrateChartPoolsComponent implements OnInit { private apiService: ApiService, private formBuilder: FormBuilder, ) { - this.seoService.setTitle($localize`:@@mining.hashrate-difficulty:Hashrate and Difficulty`); this.radioGroupForm = this.formBuilder.group({ dateSpan: '1y' }); this.radioGroupForm.controls.dateSpan.setValue('1y'); } ngOnInit(): void { + if (!this.widget) { + this.seoService.setTitle($localize`:@@mining.pools-historical-dominance:Pools Historical Dominance`); + } + this.hashrateObservable$ = this.radioGroupForm.get('dateSpan').valueChanges .pipe( startWith('1y'), switchMap((timespan) => { + this.isLoading = true; return this.apiService.getHistoricalPoolsHashrate$(timespan) .pipe( tap((data: any) => { + // Prepare series (group all hashrates data point by pool) const grouped = {}; for (const hashrate of data.hashrates) { if (!grouped.hasOwnProperty(hashrate.poolName)) { @@ -68,7 +72,6 @@ export class HashrateChartPoolsComponent implements OnInit { const series = []; const legends = []; - for (const name in grouped) { series.push({ stack: 'Total', @@ -76,12 +79,8 @@ export class HashrateChartPoolsComponent implements OnInit { showSymbol: false, data: grouped[name].map((val) => [val.timestamp * 1000, (val.share * 100).toFixed(2)]), type: 'line', - lineStyle: { - width: 0, - }, - areaStyle: { - opacity: 1, - }, + lineStyle: { width: 0 }, + areaStyle: { opacity: 1 }, smooth: true, color: poolsColor[name.replace(/[^a-zA-Z0-9]/g, "").toLowerCase()], emphasis: { @@ -115,7 +114,6 @@ export class HashrateChartPoolsComponent implements OnInit { ) / 3600 / 24; return { availableTimespanDay: availableTimespanDay, - hashrates: data }; }), ); @@ -129,7 +127,7 @@ export class HashrateChartPoolsComponent implements OnInit { grid: { right: this.right, left: this.left, - bottom: this.widget ? 30 : 60, + bottom: this.widget ? 30 : 20, top: this.widget ? 10 : 40, }, tooltip: { diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html index 0b89eb954..65672ed08 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html @@ -8,7 +8,7 @@
- Pools Hashrate Share (1y) + Mining Pools Dominance (1y)
diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss index e575a405b..fca52ca79 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss @@ -12,7 +12,7 @@ .card { background-color: #1d1f31; - height: 100%; + height: 340px; } .card-title { diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts index 3dc139b43..aac546ca1 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.ts @@ -1,4 +1,5 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { SeoService } from 'src/app/services/seo.service'; @Component({ selector: 'app-mining-dashboard', @@ -8,7 +9,9 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; }) export class MiningDashboardComponent implements OnInit { - constructor() { } + constructor(private seoService: SeoService) { + this.seoService.setTitle($localize`:@@mining.mining-dashboard:Mining Dashboard`); + } ngOnInit(): void { } 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 a3017c7af..c46a85c65 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { Router } from '@angular/router'; import { EChartsOption, PieSeriesOption } from 'echarts'; @@ -18,11 +18,12 @@ import { chartColors, poolsColor } from 'src/app/app.constants'; styles: [` .loadingGraphs { position: absolute; - top: 38%; + top: 50%; left: calc(50% - 15px); z-index: 100; } `], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class PoolRankingComponent implements OnInit { @Input() widget: boolean = false; @@ -49,13 +50,13 @@ export class PoolRankingComponent implements OnInit { private seoService: SeoService, private router: Router, ) { - this.seoService.setTitle($localize`:@@mining.mining-pools:Mining Pools`); } ngOnInit(): void { if (this.widget) { this.poolsWindowPreference = '1w'; } else { + this.seoService.setTitle($localize`:@@mining.mining-pools:Mining Pools`); this.poolsWindowPreference = this.storageService.getValue('poolsWindowPreference') ? this.storageService.getValue('poolsWindowPreference') : '1w'; } this.radioGroupForm = this.formBuilder.group({ dateSpan: this.poolsWindowPreference }); @@ -167,6 +168,7 @@ export class PoolRankingComponent implements OnInit { } this.chartOptions = { + color: chartColors, title: { text: this.widget ? '' : $localize`:@@mining.pool-chart-title:${network}:NETWORK: mining pools share`, left: 'center',