Merge pull request #4736 from mempool/mononaut/accelerator-audit-stats
Show accelerator audit total on block page
This commit is contained in:
commit
c3d90d573f
@ -56,6 +56,9 @@ class AccelerationRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async $getAccelerationInfo(poolSlug: string | null = null, height: number | null = null, interval: string | null = null): Promise<PublicAcceleration[]> {
|
public async $getAccelerationInfo(poolSlug: string | null = null, height: number | null = null, interval: string | null = null): Promise<PublicAcceleration[]> {
|
||||||
|
if (!interval || !['24h', '3d', '1w', '1m'].includes(interval)) {
|
||||||
|
interval = '1m';
|
||||||
|
}
|
||||||
interval = Common.getSqlInterval(interval);
|
interval = Common.getSqlInterval(interval);
|
||||||
|
|
||||||
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || (interval == null && poolSlug == null && height == null)) {
|
if (!config.MEMPOOL_SERVICES.ACCELERATIONS || (interval == null && poolSlug == null && height == null)) {
|
||||||
|
@ -433,6 +433,9 @@
|
|||||||
<td i18n="block.total-fees|Total fees in a block">Total fees</td>
|
<td i18n="block.total-fees|Total fees in a block">Total fees</td>
|
||||||
<td>
|
<td>
|
||||||
<app-amount [satoshis]="block.extras.totalFees" digitsInfo="1.2-3" [noFiat]="true"></app-amount>
|
<app-amount [satoshis]="block.extras.totalFees" digitsInfo="1.2-3" [noFiat]="true"></app-amount>
|
||||||
|
<span *ngIf="oobFees" class="oobFees" i18n-ngbTooltip="Acceleration Fees" ngbTooltip="Acceleration fees paid out-of-band">
|
||||||
|
+<app-amount [satoshis]="oobFees" digitsInfo="1.2-4" [noFiat]="true"></app-amount>
|
||||||
|
</span>
|
||||||
<span *ngIf="blockAudit.feeDelta" class="difference" [class.positive]="blockAudit.feeDelta <= 0" [class.negative]="blockAudit.feeDelta > 0">
|
<span *ngIf="blockAudit.feeDelta" class="difference" [class.positive]="blockAudit.feeDelta <= 0" [class.negative]="blockAudit.feeDelta > 0">
|
||||||
{{ blockAudit.feeDelta < 0 ? '+' : '' }}{{ (-blockAudit.feeDelta * 100) | amountShortener: 2 }}%
|
{{ blockAudit.feeDelta < 0 ? '+' : '' }}{{ (-blockAudit.feeDelta * 100) | amountShortener: 2 }}%
|
||||||
</span>
|
</span>
|
||||||
|
@ -288,6 +288,10 @@ h1 {
|
|||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
margin-top: 0.75rem;
|
margin-top: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.oobFees {
|
||||||
|
color: #653b9c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-col {
|
.graph-col {
|
||||||
|
@ -9,7 +9,7 @@ import { StateService } from '../../services/state.service';
|
|||||||
import { SeoService } from '../../services/seo.service';
|
import { SeoService } from '../../services/seo.service';
|
||||||
import { WebsocketService } from '../../services/websocket.service';
|
import { WebsocketService } from '../../services/websocket.service';
|
||||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||||
import { BlockAudit, BlockExtended, TransactionStripped } from '../../interfaces/node-api.interface';
|
import { AccelerationInfo, BlockAudit, BlockExtended, TransactionStripped } from '../../interfaces/node-api.interface';
|
||||||
import { ApiService } from '../../services/api.service';
|
import { ApiService } from '../../services/api.service';
|
||||||
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
||||||
import { detectWebGL } from '../../shared/graphs.utils';
|
import { detectWebGL } from '../../shared/graphs.utils';
|
||||||
@ -43,6 +43,7 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
latestBlock: BlockExtended;
|
latestBlock: BlockExtended;
|
||||||
latestBlocks: BlockExtended[] = [];
|
latestBlocks: BlockExtended[] = [];
|
||||||
transactions: Transaction[];
|
transactions: Transaction[];
|
||||||
|
oobFees: number = 0;
|
||||||
isLoadingTransactions = true;
|
isLoadingTransactions = true;
|
||||||
strippedTransactions: TransactionStripped[];
|
strippedTransactions: TransactionStripped[];
|
||||||
overviewTransitionDirection: string;
|
overviewTransitionDirection: string;
|
||||||
@ -85,6 +86,7 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
timeLtr: boolean;
|
timeLtr: boolean;
|
||||||
childChangeSubscription: Subscription;
|
childChangeSubscription: Subscription;
|
||||||
auditPrefSubscription: Subscription;
|
auditPrefSubscription: Subscription;
|
||||||
|
oobSubscription: Subscription;
|
||||||
|
|
||||||
priceSubscription: Subscription;
|
priceSubscription: Subscription;
|
||||||
blockConversion: Price;
|
blockConversion: Price;
|
||||||
@ -168,6 +170,7 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
this.page = 1;
|
this.page = 1;
|
||||||
this.error = undefined;
|
this.error = undefined;
|
||||||
this.fees = undefined;
|
this.fees = undefined;
|
||||||
|
this.oobFees = 0;
|
||||||
|
|
||||||
if (history.state.data && history.state.data.blockHeight) {
|
if (history.state.data && history.state.data.blockHeight) {
|
||||||
this.blockHeight = history.state.data.blockHeight;
|
this.blockHeight = history.state.data.blockHeight;
|
||||||
@ -446,7 +449,7 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
inBlock[tx.txid] = true;
|
inBlock[tx.txid] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockAudit.feeDelta = blockAudit.expectedFees > 0 ? (blockAudit.expectedFees - this.block.extras.totalFees) / blockAudit.expectedFees : 0;
|
blockAudit.feeDelta = blockAudit.expectedFees > 0 ? (blockAudit.expectedFees - (this.block.extras.totalFees + this.oobFees)) / blockAudit.expectedFees : 0;
|
||||||
blockAudit.weightDelta = blockAudit.expectedWeight > 0 ? (blockAudit.expectedWeight - this.block.weight) / blockAudit.expectedWeight : 0;
|
blockAudit.weightDelta = blockAudit.expectedWeight > 0 ? (blockAudit.expectedWeight - this.block.weight) / blockAudit.expectedWeight : 0;
|
||||||
blockAudit.txDelta = blockAudit.template.length > 0 ? (blockAudit.template.length - this.block.tx_count) / blockAudit.template.length : 0;
|
blockAudit.txDelta = blockAudit.template.length > 0 ? (blockAudit.template.length - this.block.tx_count) / blockAudit.template.length : 0;
|
||||||
this.blockAudit = blockAudit;
|
this.blockAudit = blockAudit;
|
||||||
@ -462,6 +465,32 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
this.setupBlockGraphs();
|
this.setupBlockGraphs();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.oobSubscription = block$.pipe(
|
||||||
|
switchMap((block) => this.apiService.getAccelerationsByHeight$(block.height)
|
||||||
|
.pipe(
|
||||||
|
map(accelerations => {
|
||||||
|
return { block, accelerations };
|
||||||
|
}),
|
||||||
|
catchError((err) => {
|
||||||
|
return of({ block, accelerations: [] });
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
).subscribe(({ block, accelerations}) => {
|
||||||
|
let totalFees = 0;
|
||||||
|
for (const acc of accelerations) {
|
||||||
|
totalFees += acc.boost_cost;
|
||||||
|
}
|
||||||
|
this.oobFees = totalFees;
|
||||||
|
if (block && this.block && this.blockAudit && block?.height === this.block?.height) {
|
||||||
|
this.blockAudit.feeDelta = this.blockAudit.expectedFees > 0 ? (this.blockAudit.expectedFees - (this.block.extras.totalFees + this.oobFees)) / this.blockAudit.expectedFees : 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.error = error;
|
||||||
|
this.isLoadingBlock = false;
|
||||||
|
this.isLoadingOverview = false;
|
||||||
|
});
|
||||||
|
|
||||||
this.networkChangedSubscription = this.stateService.networkChanged$
|
this.networkChangedSubscription = this.stateService.networkChanged$
|
||||||
.subscribe((network) => this.network = network);
|
.subscribe((network) => this.network = network);
|
||||||
|
|
||||||
@ -529,6 +558,7 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
this.unsubscribeNextBlockSubscriptions();
|
this.unsubscribeNextBlockSubscriptions();
|
||||||
this.childChangeSubscription?.unsubscribe();
|
this.childChangeSubscription?.unsubscribe();
|
||||||
this.priceSubscription?.unsubscribe();
|
this.priceSubscription?.unsubscribe();
|
||||||
|
this.oobSubscription?.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsubscribeNextBlockSubscriptions() {
|
unsubscribeNextBlockSubscriptions() {
|
||||||
|
@ -403,4 +403,18 @@ export interface AccelerationHistoryParams {
|
|||||||
blockHeight?: number;
|
blockHeight?: number;
|
||||||
page?: number;
|
page?: number;
|
||||||
pageLength?: number;
|
pageLength?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccelerationInfo {
|
||||||
|
txid: string,
|
||||||
|
height: number,
|
||||||
|
pool: {
|
||||||
|
id: number,
|
||||||
|
slug: string,
|
||||||
|
name: string,
|
||||||
|
},
|
||||||
|
effective_vsize: number,
|
||||||
|
effective_fee: number,
|
||||||
|
boost_rate: number,
|
||||||
|
boost_cost: number,
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
|
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
|
||||||
import { CpfpInfo, OptimizedMempoolStats, AddressInformation, LiquidPegs, ITranslators,
|
import { CpfpInfo, OptimizedMempoolStats, AddressInformation, LiquidPegs, ITranslators,
|
||||||
PoolStat, BlockExtended, TransactionStripped, RewardStats, AuditScore, BlockSizesAndWeights, RbfTree, BlockAudit, Acceleration, AccelerationHistoryParams, CurrentPegs, AuditStatus, FederationAddress, FederationUtxo, RecentPeg, PegsVolume } from '../interfaces/node-api.interface';
|
PoolStat, BlockExtended, TransactionStripped, RewardStats, AuditScore, BlockSizesAndWeights, RbfTree, BlockAudit, Acceleration, AccelerationHistoryParams, CurrentPegs, AuditStatus, FederationAddress, FederationUtxo, RecentPeg, PegsVolume, AccelerationInfo } from '../interfaces/node-api.interface';
|
||||||
import { BehaviorSubject, Observable, catchError, filter, of, shareReplay, take, tap } from 'rxjs';
|
import { BehaviorSubject, Observable, catchError, filter, of, shareReplay, take, tap } from 'rxjs';
|
||||||
import { StateService } from './state.service';
|
import { StateService } from './state.service';
|
||||||
import { Transaction } from '../interfaces/electrs.interface';
|
import { Transaction } from '../interfaces/electrs.interface';
|
||||||
@ -424,4 +424,22 @@ export class ApiService {
|
|||||||
(timestamp ? `?timestamp=${timestamp}` : '')
|
(timestamp ? `?timestamp=${timestamp}` : '')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAccelerationsByPool$(slug: string): Observable<AccelerationInfo[]> {
|
||||||
|
return this.httpClient.get<AccelerationInfo[]>(
|
||||||
|
this.apiBaseUrl + this.apiBasePath + `/api/v1/accelerations/pool/${slug}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAccelerationsByHeight$(height: number): Observable<AccelerationInfo[]> {
|
||||||
|
return this.httpClient.get<AccelerationInfo[]>(
|
||||||
|
this.apiBaseUrl + this.apiBasePath + `/api/v1/accelerations/block/${height}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRecentAccelerations$(interval: string | undefined): Observable<AccelerationInfo[]> {
|
||||||
|
return this.httpClient.get<AccelerationInfo[]>(
|
||||||
|
this.apiBaseUrl + this.apiBasePath + '/api/v1/accelerations/interval' + (interval !== undefined ? `/${interval}` : '')
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user