mirror of
https://github.com/mempool/mempool.git
synced 2025-02-24 14:50:52 +01:00
warn on re-index - fix hash indexing state issue - cleanup ui mining
This commit is contained in:
parent
54ccfe070e
commit
ec40231f93
11 changed files with 45 additions and 53 deletions
|
@ -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"');
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<any>(query, [Math.round(new Date().getTime() / 1000)]);
|
||||
|
||||
await connection.query<any>(query, (val === null) ? [Math.round(new Date().getTime() / 1000)] : [val]);
|
||||
connection.release();
|
||||
}
|
||||
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -31,28 +31,4 @@
|
|||
<div class="spinner-border text-light"></div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="mt-3" *ngIf="!widget">
|
||||
<table class="table table-borderless table-sm text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th i18n="mining.rank">Block</th>
|
||||
<th class="d-none d-md-block" i18n="block.timestamp">Timestamp</th>
|
||||
<th i18n="mining.adjusted">Adjusted</th>
|
||||
<th i18n="mining.difficulty">Difficulty</th>
|
||||
<th i18n="mining.change">Change</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody *ngIf="(hashrateObservable$ | async) as data">
|
||||
<tr *ngFor="let diffChange of data.difficulty">
|
||||
<td><a [routerLink]="['/block' | relativeUrl, diffChange.height]">{{ diffChange.height }}</a></td>
|
||||
<td class="d-none d-md-block">‎{{ diffChange.timestamp * 1000 | date:'yyyy-MM-dd HH:mm' }}</td>
|
||||
<td><app-time-since [time]="diffChange.timestamp" [fastRender]="true"></app-time-since></td>
|
||||
<td class="d-none d-md-block">{{ formatNumber(diffChange.difficulty, locale, '1.2-2') }}</td>
|
||||
<td class="d-block d-md-none">{{ diffChange.difficultyShorten }}</td>
|
||||
<td [style]="diffChange.change >= 0 ? 'color: #42B747' : 'color: #B74242'">{{ formatNumber(diffChange.change, locale, '1.2-2') }}%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div> -->
|
||||
|
||||
</div>
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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<any>;
|
||||
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: {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<a class="link" href="" [routerLink]="['/mining/hashrate/pools' | relativeUrl]" i18n="mining.pools-hashrate">
|
||||
Pools Hashrate Share (1y)
|
||||
Mining Pools Dominance (1y)
|
||||
</a>
|
||||
</h5>
|
||||
<app-hashrate-chart-pools [widget]=true></app-hashrate-chart-pools>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
.card {
|
||||
background-color: #1d1f31;
|
||||
height: 100%;
|
||||
height: 340px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
|
|
|
@ -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 {
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Add table
Reference in a new issue