Merge pull request #1687 from mempool/nymkappa/feature/use-block-count-timespan

Replace all oldestIndexedBlockTimestamp with X-total-count header
This commit is contained in:
wiz 2022-05-25 20:32:44 +09:00 committed by GitHub
commit cba9930410
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 104 additions and 127 deletions

View File

@ -89,7 +89,6 @@ class Mining {
}); });
poolsStatistics['pools'] = poolsStats; poolsStatistics['pools'] = poolsStats;
poolsStatistics['oldestIndexedBlockTimestamp'] = await BlocksRepository.$oldestBlockTimestamp();
const blockCount: number = await BlocksRepository.$blockCount(null, interval); const blockCount: number = await BlocksRepository.$blockCount(null, interval);
poolsStatistics['blockCount'] = blockCount; poolsStatistics['blockCount'] = blockCount;

View File

@ -669,14 +669,12 @@ class Routes {
public async $getHistoricalBlockFeeRates(req: Request, res: Response) { public async $getHistoricalBlockFeeRates(req: Request, res: Response) {
try { try {
const blockFeeRates = await mining.$getHistoricalBlockFeeRates(req.params.interval); const blockFeeRates = await mining.$getHistoricalBlockFeeRates(req.params.interval);
const oldestIndexedBlockTimestamp = await BlocksRepository.$oldestBlockTimestamp(); const blockCount = await BlocksRepository.$blockCount(null, null);
res.header('Pragma', 'public'); res.header('Pragma', 'public');
res.header('Cache-control', 'public'); res.header('Cache-control', 'public');
res.header('X-total-count', blockCount.toString());
res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
res.json({ res.json(blockFeeRates);
oldestIndexedBlockTimestamp: oldestIndexedBlockTimestamp,
blockFeeRates: blockFeeRates,
});
} catch (e) { } catch (e) {
res.status(500).send(e instanceof Error ? e.message : e); res.status(500).send(e instanceof Error ? e.message : e);
} }

View File

@ -8,34 +8,34 @@
</button> </button>
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats"> <form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan"> <div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 1"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 144">
<input ngbButton type="radio" [value]="'24h'" fragment="24h"> 24h <input ngbButton type="radio" [value]="'24h'" fragment="24h"> 24h
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 3"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 432">
<input ngbButton type="radio" [value]="'3d'" fragment="3d"> 3D <input ngbButton type="radio" [value]="'3d'" fragment="3d"> 3D
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 7"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 1008">
<input ngbButton type="radio" [value]="'1w'" fragment="1w"> 1W <input ngbButton type="radio" [value]="'1w'" fragment="1w"> 1W
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 30"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 4320">
<input ngbButton type="radio" [value]="'1m'" fragment="1m"> 1M <input ngbButton type="radio" [value]="'1m'" fragment="1m"> 1M
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 90"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 12960">
<input ngbButton type="radio" [value]="'3m'" fragment="3m"> 3M <input ngbButton type="radio" [value]="'3m'" fragment="3m"> 3M
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 180"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 25920">
<input ngbButton type="radio" [value]="'6m'" fragment="6m"> 6M <input ngbButton type="radio" [value]="'6m'" fragment="6m"> 6M
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 365"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 52560">
<input ngbButton type="radio" [value]="'1y'" fragment="1y"> 1Y <input ngbButton type="radio" [value]="'1y'" fragment="1y"> 1Y
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 730"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 105120">
<input ngbButton type="radio" [value]="'2y'" fragment="2y"> 2Y <input ngbButton type="radio" [value]="'2y'" fragment="2y"> 2Y
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 1095"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 157680">
<input ngbButton type="radio" [value]="'3y'" fragment="3y"> 3Y <input ngbButton type="radio" [value]="'3y'" fragment="3y"> 3Y
</label> </label>
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay > 1095"> <label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount > 157680">
<input ngbButton type="radio" [value]="'all'" fragment="all"> ALL <input ngbButton type="radio" [value]="'all'" fragment="all"> ALL
</label> </label>
</div> </div>

View File

@ -76,7 +76,7 @@ export class BlockFeeRatesGraphComponent implements OnInit {
this.isLoading = true; this.isLoading = true;
return this.apiService.getHistoricalBlockFeeRates$(timespan) return this.apiService.getHistoricalBlockFeeRates$(timespan)
.pipe( .pipe(
tap((data: any) => { tap((response) => {
// Group by percentile // Group by percentile
const seriesData = { const seriesData = {
'Min': [], 'Min': [],
@ -87,7 +87,7 @@ export class BlockFeeRatesGraphComponent implements OnInit {
'90th': [], '90th': [],
'Max': [] 'Max': []
}; };
for (const rate of data.blockFeeRates) { for (const rate of response.body) {
const timestamp = rate.timestamp * 1000; const timestamp = rate.timestamp * 1000;
seriesData['Min'].push([timestamp, rate.avgFee_0, rate.avgHeight]); seriesData['Min'].push([timestamp, rate.avgFee_0, rate.avgHeight]);
seriesData['10th'].push([timestamp, rate.avgFee_10, rate.avgHeight]); seriesData['10th'].push([timestamp, rate.avgFee_10, rate.avgHeight]);
@ -130,13 +130,9 @@ export class BlockFeeRatesGraphComponent implements OnInit {
}); });
this.isLoading = false; this.isLoading = false;
}), }),
map((data: any) => { map((response) => {
const availableTimespanDay = (
(new Date().getTime() / 1000) - (data.oldestIndexedBlockTimestamp)
) / 3600 / 24;
return { return {
availableTimespanDay: availableTimespanDay, blockCount: parseInt(response.headers.get('x-total-count'), 10),
}; };
}), }),
); );

View File

@ -34,10 +34,6 @@ export class DifficultyAdjustmentsTable implements OnInit {
.pipe( .pipe(
map((response) => { map((response) => {
const data = response.body; const data = response.body;
const availableTimespanDay = (
(new Date().getTime() / 1000) - (data.oldestIndexedBlockTimestamp)
) / 3600 / 24;
const tableData = []; const tableData = [];
for (let i = data.difficulty.length - 1; i > 0; --i) { for (let i = data.difficulty.length - 1; i > 0; --i) {
const selectedPowerOfTen: any = selectPowerOfTen(data.difficulty[i].difficulty); const selectedPowerOfTen: any = selectPowerOfTen(data.difficulty[i].difficulty);
@ -53,7 +49,6 @@ export class DifficultyAdjustmentsTable implements OnInit {
this.isLoading = false; this.isLoading = false;
return { return {
availableTimespanDay: availableTimespanDay,
difficulty: tableData.slice(0, 6), difficulty: tableData.slice(0, 6),
}; };
}), }),

View File

@ -3049,7 +3049,6 @@ export const restApiDocsData = [
"slug": "antpool" "slug": "antpool"
}, },
... ...
"oldestIndexedBlockTimestamp": 1231006505,
"blockCount": 1005, "blockCount": 1005,
"lastEstimatedHashrate": 230086716765559200000 "lastEstimatedHashrate": 230086716765559200000
}` }`
@ -3080,7 +3079,6 @@ export const restApiDocsData = [
}, },
... ...
], ],
"oldestIndexedBlockTimestamp": 1296688602,
"blockCount": 2226180, "blockCount": 2226180,
"lastEstimatedHashrate": 602244182177430.8 "lastEstimatedHashrate": 602244182177430.8
}` }`
@ -4025,111 +4023,103 @@ export const restApiDocsData = [
esModule: [], esModule: [],
commonJS: [], commonJS: [],
curl: [`1m`], curl: [`1m`],
response: `{ response: `[
"oldestIndexedBlockTimestamp": 1571434851, {
"blockFeeRates": [ "avgHeight": 732152,
{ "timestamp": 1650132959,
"avgHeight": 732152, "avgFee_0": 1,
"timestamp": 1650132959, "avgFee_10": 2,
"avgFee_0": 1, "avgFee_25": 2,
"avgFee_10": 2, "avgFee_50": 3,
"avgFee_25": 2, "avgFee_75": 4,
"avgFee_50": 3, "avgFee_90": 8,
"avgFee_75": 4, "avgFee_100": 393
"avgFee_90": 8, },
"avgFee_100": 393 {
}, "avgHeight": 732158,
{ "timestamp": 1650134432,
"avgHeight": 732158, "avgFee_0": 1,
"timestamp": 1650134432, "avgFee_10": 1,
"avgFee_0": 1, "avgFee_25": 2,
"avgFee_10": 1, "avgFee_50": 4,
"avgFee_25": 2, "avgFee_75": 6,
"avgFee_50": 4, "avgFee_90": 10,
"avgFee_75": 6, "avgFee_100": 240
"avgFee_90": 10, },
"avgFee_100": 240 {
}, "avgHeight": 732161,
{ "timestamp": 1650135818,
"avgHeight": 732161, "avgFee_0": 1,
"timestamp": 1650135818, "avgFee_10": 1,
"avgFee_0": 1, "avgFee_25": 1,
"avgFee_10": 1, "avgFee_50": 2,
"avgFee_25": 1, "avgFee_75": 5,
"avgFee_50": 2, "avgFee_90": 8,
"avgFee_75": 5, "avgFee_100": 251
"avgFee_90": 8, },
"avgFee_100": 251 ...
}, ]`
...
]
}`
}, },
codeSampleTestnet: { codeSampleTestnet: {
esModule: [], esModule: [],
commonJS: [], commonJS: [],
curl: [`1m`], curl: [`1m`],
response: `{ response: `[
"oldestIndexedBlockTimestamp": 1296688602, {
"blockFeeRates": [ "avgHeight": 2196306,
{ "timestamp": 1650360168,
"avgHeight": 2196306, "avgFee_0": 1,
"timestamp": 1650360168, "avgFee_10": 1,
"avgFee_0": 1, "avgFee_25": 1,
"avgFee_10": 1, "avgFee_50": 1,
"avgFee_25": 1, "avgFee_75": 2,
"avgFee_50": 1, "avgFee_90": 28,
"avgFee_75": 2, "avgFee_100": 2644
"avgFee_90": 28, },
"avgFee_100": 2644 {
}, "avgHeight": 2196308,
{ "timestamp": 1650361209,
"avgHeight": 2196308, "avgFee_0": 1,
"timestamp": 1650361209, "avgFee_10": 1,
"avgFee_0": 1, "avgFee_25": 1,
"avgFee_10": 1, "avgFee_50": 4,
"avgFee_25": 1, "avgFee_75": 12,
"avgFee_50": 4, "avgFee_90": 65,
"avgFee_75": 12, "avgFee_100": 102
"avgFee_90": 65, },
"avgFee_100": 102 ...
}, ]`
...
]
}`
}, },
codeSampleSignet: { codeSampleSignet: {
esModule: [], esModule: [],
commonJS: [], commonJS: [],
curl: [`1m`], curl: [`1m`],
response: `{ response: `{
"oldestIndexedBlockTimestamp": 1598918400, "blockFeeRates": [
"blockFeeRates": [ {
{ "avgHeight": 86620,
"avgHeight": 86620, "timestamp": 1650360010,
"timestamp": 1650360010, "avgFee_0": 1,
"avgFee_0": 1, "avgFee_10": 1,
"avgFee_10": 1, "avgFee_25": 1,
"avgFee_25": 1, "avgFee_50": 1,
"avgFee_50": 1, "avgFee_75": 1,
"avgFee_75": 1, "avgFee_90": 1,
"avgFee_90": 1, "avgFee_100": 1
"avgFee_100": 1 },
}, {
{ "avgHeight": 86623,
"avgHeight": 86623, "timestamp": 1650361330,
"timestamp": 1650361330, "avgFee_0": 1,
"avgFee_0": 1, "avgFee_10": 1,
"avgFee_10": 1, "avgFee_25": 1,
"avgFee_25": 1, "avgFee_50": 1,
"avgFee_50": 1, "avgFee_75": 1,
"avgFee_75": 1, "avgFee_90": 1,
"avgFee_90": 1, "avgFee_100": 1
"avgFee_100": 1 },
}, ...
... ]`
]
}`
}, },
codeSampleLiquid: emptyCodeSample, codeSampleLiquid: emptyCodeSample,
codeSampleLiquidTestnet: emptyCodeSample, codeSampleLiquidTestnet: emptyCodeSample,

View File

@ -76,7 +76,6 @@ export interface SinglePoolStats {
export interface PoolsStats { export interface PoolsStats {
blockCount: number; blockCount: number;
lastEstimatedHashrate: number; lastEstimatedHashrate: number;
oldestIndexedBlockTimestamp: number;
pools: SinglePoolStats[]; pools: SinglePoolStats[];
} }

View File

@ -189,7 +189,7 @@ export class ApiService {
getHistoricalBlockFeeRates$(interval: string | undefined) : Observable<any> { getHistoricalBlockFeeRates$(interval: string | undefined) : Observable<any> {
return this.httpClient.get<any[]>( return this.httpClient.get<any[]>(
this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/blocks/fee-rates` + this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/blocks/fee-rates` +
(interval !== undefined ? `/${interval}` : '') (interval !== undefined ? `/${interval}` : ''), { observe: 'response' }
); );
} }