From 7491fb512c80f35ea23d038dae55bad5e3fc9ce1 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Tue, 5 Mar 2024 00:40:49 +0000 Subject: [PATCH 1/2] Show accelerator audit total on block page --- .../repositories/AccelerationRepository.ts | 3 ++ .../app/components/block/block.component.html | 3 ++ .../app/components/block/block.component.scss | 4 +++ .../app/components/block/block.component.ts | 34 +++++++++++++++++-- .../src/app/interfaces/node-api.interface.ts | 14 ++++++++ frontend/src/app/services/api.service.ts | 20 ++++++++++- 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/backend/src/repositories/AccelerationRepository.ts b/backend/src/repositories/AccelerationRepository.ts index 868f8526f..b30e563ef 100644 --- a/backend/src/repositories/AccelerationRepository.ts +++ b/backend/src/repositories/AccelerationRepository.ts @@ -56,6 +56,9 @@ class AccelerationRepository { } public async $getAccelerationInfo(poolSlug: string | null = null, height: number | null = null, interval: string | null = null): Promise { + if (!interval || !['24h', '3d', '1w', '1m'].includes(interval)) { + interval = '1m'; + } interval = Common.getSqlInterval(interval); if (!config.MEMPOOL_SERVICES.ACCELERATIONS || (interval == null && poolSlug == null && height == null)) { diff --git a/frontend/src/app/components/block/block.component.html b/frontend/src/app/components/block/block.component.html index 89699a68c..777be0907 100644 --- a/frontend/src/app/components/block/block.component.html +++ b/frontend/src/app/components/block/block.component.html @@ -433,6 +433,9 @@ Total fees + + + + {{ blockAudit.feeDelta < 0 ? '+' : '' }}{{ (-blockAudit.feeDelta * 100) | amountShortener: 2 }}% diff --git a/frontend/src/app/components/block/block.component.scss b/frontend/src/app/components/block/block.component.scss index 6deb2cb4b..4dd079eb8 100644 --- a/frontend/src/app/components/block/block.component.scss +++ b/frontend/src/app/components/block/block.component.scss @@ -288,6 +288,10 @@ h1 { @media (max-width: 767.98px) { margin-top: 0.75rem; } + + .oobFees { + color: #653b9c; + } } .graph-col { diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts index 5bba24852..c68108af1 100644 --- a/frontend/src/app/components/block/block.component.ts +++ b/frontend/src/app/components/block/block.component.ts @@ -9,7 +9,7 @@ import { StateService } from '../../services/state.service'; import { SeoService } from '../../services/seo.service'; import { WebsocketService } from '../../services/websocket.service'; 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 { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component'; import { detectWebGL } from '../../shared/graphs.utils'; @@ -43,6 +43,7 @@ export class BlockComponent implements OnInit, OnDestroy { latestBlock: BlockExtended; latestBlocks: BlockExtended[] = []; transactions: Transaction[]; + oobFees: number = 0; isLoadingTransactions = true; strippedTransactions: TransactionStripped[]; overviewTransitionDirection: string; @@ -85,6 +86,7 @@ export class BlockComponent implements OnInit, OnDestroy { timeLtr: boolean; childChangeSubscription: Subscription; auditPrefSubscription: Subscription; + oobSubscription: Subscription; priceSubscription: Subscription; blockConversion: Price; @@ -168,6 +170,7 @@ export class BlockComponent implements OnInit, OnDestroy { this.page = 1; this.error = undefined; this.fees = undefined; + this.oobFees = 0; if (history.state.data && history.state.data.blockHeight) { this.blockHeight = history.state.data.blockHeight; @@ -446,7 +449,7 @@ export class BlockComponent implements OnInit, OnDestroy { 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.txDelta = blockAudit.template.length > 0 ? (blockAudit.template.length - this.block.tx_count) / blockAudit.template.length : 0; this.blockAudit = blockAudit; @@ -462,6 +465,32 @@ export class BlockComponent implements OnInit, OnDestroy { 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.height === this.block.height && this.blockAudit) { + 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$ .subscribe((network) => this.network = network); @@ -529,6 +558,7 @@ export class BlockComponent implements OnInit, OnDestroy { this.unsubscribeNextBlockSubscriptions(); this.childChangeSubscription?.unsubscribe(); this.priceSubscription?.unsubscribe(); + this.oobSubscription?.unsubscribe(); } unsubscribeNextBlockSubscriptions() { diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts index e5764e785..07ec4f68d 100644 --- a/frontend/src/app/interfaces/node-api.interface.ts +++ b/frontend/src/app/interfaces/node-api.interface.ts @@ -400,4 +400,18 @@ export interface AccelerationHistoryParams { blockHeight?: number; page?: 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, } \ No newline at end of file diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts index 7bd41c8a0..f90bfb838 100644 --- a/frontend/src/app/services/api.service.ts +++ b/frontend/src/app/services/api.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http'; 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 { StateService } from './state.service'; import { Transaction } from '../interfaces/electrs.interface'; @@ -412,4 +412,22 @@ export class ApiService { (timestamp ? `?timestamp=${timestamp}` : '') ); } + + getAccelerationsByPool$(slug: string): Observable { + return this.httpClient.get( + this.apiBaseUrl + this.apiBasePath + `/api/v1/accelerations/pool/${slug}` + ); + } + + getAccelerationsByHeight$(height: number): Observable { + return this.httpClient.get( + this.apiBaseUrl + this.apiBasePath + `/api/v1/accelerations/block/${height}` + ); + } + + getRecentAccelerations$(interval: string | undefined): Observable { + return this.httpClient.get( + this.apiBaseUrl + this.apiBasePath + '/api/v1/accelerations/interval' + (interval !== undefined ? `/${interval}` : '') + ); + } } From e7788133faf3fa53b79aef0755f1cffca4b669fc Mon Sep 17 00:00:00 2001 From: Mononaut Date: Thu, 7 Mar 2024 19:52:42 +0000 Subject: [PATCH 2/2] Add missing null check in block accelerations subscription --- frontend/src/app/components/block/block.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts index c68108af1..1eb1c4798 100644 --- a/frontend/src/app/components/block/block.component.ts +++ b/frontend/src/app/components/block/block.component.ts @@ -481,7 +481,7 @@ export class BlockComponent implements OnInit, OnDestroy { totalFees += acc.boost_cost; } this.oobFees = totalFees; - if (block.height === this.block.height && this.blockAudit) { + 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; } },