Merge pull request #1496 from mempool/nymkappa/bugfix/dont-assume-init-block-count

Mining stats does not depends on the websocket blocks number anymore
This commit is contained in:
softsimon 2022-04-03 01:08:24 +04:00 committed by GitHub
commit f6b7a94b36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 19 deletions

View File

@ -386,10 +386,14 @@ class BlocksRepository {
connection = await DB.getConnection(); connection = await DB.getConnection();
// We need to use a subquery // We need to use a subquery
const query = `SELECT SUM(reward) as totalReward, SUM(fees) as totalFee, SUM(tx_count) as totalTx const query = `
FROM (SELECT reward, fees, tx_count FROM blocks ORDER by height DESC LIMIT ${blockCount}) as sub`; SELECT MIN(height) as startBlock, MAX(height) as endBlock, SUM(reward) as totalReward, SUM(fees) as totalFee, SUM(tx_count) as totalTx
FROM
(SELECT height, reward, fees, tx_count FROM blocks
ORDER by height DESC
LIMIT ?) as sub`;
const [rows]: any = await connection.query(query); const [rows]: any = await connection.query(query, [blockCount]);
connection.release(); connection.release();
return rows[0]; return rows[0];

View File

@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs'; import { concat, Observable } from 'rxjs';
import { map, skip, switchMap } from 'rxjs/operators'; import { map, switchMap, tap } from 'rxjs/operators';
import { ApiService } from 'src/app/services/api.service'; import { ApiService } from 'src/app/services/api.service';
import { StateService } from 'src/app/services/state.service'; import { StateService } from 'src/app/services/state.service';
@ -12,25 +12,39 @@ import { StateService } from 'src/app/services/state.service';
}) })
export class RewardStatsComponent implements OnInit { export class RewardStatsComponent implements OnInit {
public $rewardStats: Observable<any>; public $rewardStats: Observable<any>;
private lastBlockHeight: number;
constructor(private apiService: ApiService, private stateService: StateService) { } constructor(private apiService: ApiService, private stateService: StateService) { }
ngOnInit(): void { ngOnInit(): void {
this.$rewardStats = this.stateService.blocks$ this.$rewardStats = concat(
// We fetch the latest reward stats when the page load and
// wait for the API response before listening to websocket blocks
this.apiService.getRewardStats$()
.pipe(
tap((stats) => {
this.lastBlockHeight = stats.endBlock;
})
),
// Or when we receive a newer block, newer than the latest reward stats api call
this.stateService.blocks$
.pipe(
switchMap((block) => {
if (block[0].height <= this.lastBlockHeight) {
return []; // Return an empty stream so the last pipe is not executed
}
this.lastBlockHeight = block[0].height;
return this.apiService.getRewardStats$();
})
)
)
.pipe( .pipe(
// (we always receives some blocks at start so only trigger for the last one) map((stats) => {
skip(this.stateService.env.MEMPOOL_BLOCKS_AMOUNT - 1), return {
switchMap(() => { totalReward: stats.totalReward,
return this.apiService.getRewardStats$() rewardPerTx: stats.totalReward / stats.totalTx,
.pipe( feePerTx: stats.totalFee / stats.totalTx,
map((stats) => { };
return {
totalReward: stats.totalReward,
rewardPerTx: stats.totalReward / stats.totalTx,
feePerTx: stats.totalFee / stats.totalTx,
};
})
);
}) })
); );
} }

View File

@ -119,6 +119,8 @@ export interface BlockExtended extends Block {
} }
export interface RewardStats { export interface RewardStats {
startBlock: number;
endBlock: number;
totalReward: number; totalReward: number;
totalFee: number; totalFee: number;
totalTx: number; totalTx: number;