From 756fac7270c50fa88ccf6f71bb9389cf5e5a0da4 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Fri, 14 Jul 2023 11:52:07 +0900 Subject: [PATCH] Switch "latest blocks" to "latest replacements" --- .../app/dashboard/dashboard.component.html | 39 +++++------ .../app/dashboard/dashboard.component.scss | 46 ++++++------ .../src/app/dashboard/dashboard.component.ts | 70 ++++++++++++++----- 3 files changed, 88 insertions(+), 67 deletions(-) diff --git a/frontend/src/app/dashboard/dashboard.component.html b/frontend/src/app/dashboard/dashboard.component.html index 620678a28..90ec01e1d 100644 --- a/frontend/src/app/dashboard/dashboard.component.html +++ b/frontend/src/app/dashboard/dashboard.component.html @@ -75,36 +75,31 @@
- -
Latest blocks
+
+
Latest Replacements
 
- +
- - - - - + + + + - - - - + - - + + diff --git a/frontend/src/app/dashboard/dashboard.component.scss b/frontend/src/app/dashboard/dashboard.component.scss index eb466fc16..5633a3c7e 100644 --- a/frontend/src/app/dashboard/dashboard.component.scss +++ b/frontend/src/app/dashboard/dashboard.component.scss @@ -175,40 +175,34 @@ height: 18px; } -.lastest-blocks-table { +.lastest-replacements-table { width: 100%; text-align: left; + table-layout:fixed; tr, td, th { border: 0px; - padding-top: 0.65rem !important; - padding-bottom: 0.7rem !important; + padding-top: 0.71rem !important; + padding-bottom: 0.75rem !important; } - .table-cell-height { - width: 15%; + td { + overflow:hidden; + width: 25%; } - .table-cell-mined { - width: 35%; - text-align: left; + .table-cell-txid { + width: 33%; + text-align: start; } - .table-cell-transaction-count { - display: none; - text-align: right; - width: 20%; - display: table-cell; + .table-cell-old-fee { + width: 33%; + text-align: end; } - .table-cell-size { - display: none; - text-align: center; - width: 30%; - @media (min-width: 485px) { - display: table-cell; - } - @media (min-width: 768px) { - display: none; - } - @media (min-width: 992px) { - display: table-cell; - } + .table-cell-new-fee { + width: 33%; + text-align: end; + } + .table-cell-badges { + width: 25%; + text-align: end; } } diff --git a/frontend/src/app/dashboard/dashboard.component.ts b/frontend/src/app/dashboard/dashboard.component.ts index 6cf487be6..4ef4501aa 100644 --- a/frontend/src/app/dashboard/dashboard.component.ts +++ b/frontend/src/app/dashboard/dashboard.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; import { combineLatest, merge, Observable, of, Subscription } from 'rxjs'; import { filter, map, scan, share, switchMap, tap } from 'rxjs/operators'; -import { BlockExtended, OptimizedMempoolStats } from '../interfaces/node-api.interface'; +import { BlockExtended, OptimizedMempoolStats, RbfTree } from '../interfaces/node-api.interface'; import { MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface'; import { ApiService } from '../services/api.service'; import { StateService } from '../services/state.service'; @@ -25,6 +25,17 @@ interface MempoolStatsData { weightPerSecond: any; } +interface ReplacementInfo { + tree: RbfTree; + mined: boolean; + fullRbf: boolean; + txid: string; + oldFee: number; + oldVsize: number; + newFee: number; + newVsize: number; +} + @Component({ selector: 'app-dashboard', templateUrl: './dashboard.component.html', @@ -38,8 +49,8 @@ export class DashboardComponent implements OnInit, OnDestroy { mempoolInfoData$: Observable; mempoolLoadingStatus$: Observable; vBytesPerSecondLimit = 1667; - blocks$: Observable; transactions$: Observable; + replacements$: Observable; latestBlockHeight: number; mempoolTransactionsWeightPerSecondData: any; mempoolStats$: Observable; @@ -64,6 +75,7 @@ export class DashboardComponent implements OnInit, OnDestroy { this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$; this.seoService.resetTitle(); this.websocketService.want(['blocks', 'stats', 'mempool-blocks', 'live-2h-chart']); + this.websocketService.startTrackRbf('all'); this.network$ = merge(of(''), this.stateService.networkChanged$); this.mempoolLoadingStatus$ = this.stateService.loadingIndicators$ .pipe( @@ -130,23 +142,6 @@ export class DashboardComponent implements OnInit, OnDestroy { }), ); - this.blocks$ = this.stateService.blocks$ - .pipe( - tap((blocks) => { - this.latestBlockHeight = blocks[0].height; - }), - switchMap((blocks) => { - if (this.stateService.env.MINING_DASHBOARD === true) { - for (const block of blocks) { - // @ts-ignore: Need to add an extra field for the template - block.extras.pool.logo = `/resources/mining-pools/` + - block.extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg'; - } - } - return of(blocks.slice(0, 6)); - }) - ); - this.transactions$ = this.stateService.transactions$ .pipe( scan((acc, tx) => { @@ -159,6 +154,31 @@ export class DashboardComponent implements OnInit, OnDestroy { }, []), ); + this.replacements$ = this.stateService.rbfLatest$.pipe( + switchMap((rbfList) => { + const replacements = rbfList.slice(0, 6).map(rbfTree => { + let oldFee = 0; + let oldVsize = 0; + for (const replaced of rbfTree.replaces) { + oldFee += replaced.tx.fee; + oldVsize += replaced.tx.vsize; + } + this.checkFullRbf(rbfTree); + return { + tree: rbfTree, + txid: rbfTree.tx.txid, + mined: rbfTree.tx.mined, + fullRbf: rbfTree.tx.fullRbf, + oldFee, + oldVsize, + newFee: rbfTree.tx.fee, + newVsize: rbfTree.tx.vsize, + }; + }); + return of(replacements); + }) + ); + this.mempoolStats$ = this.stateService.connectionState$ .pipe( filter((state) => state === 2), @@ -219,4 +239,16 @@ export class DashboardComponent implements OnInit, OnDestroy { trackByBlock(index: number, block: BlockExtended) { return block.height; } + + checkFullRbf(tree: RbfTree): void { + let fullRbf = false; + for (const replaced of tree.replaces) { + if (!replaced.tx.rbf) { + fullRbf = true; + } + replaced.replacedBy = tree.tx; + this.checkFullRbf(replaced); + } + tree.tx.fullRbf = fullRbf; + } }
HeightMinedPoolTXsSizeTXIDOld feeNew fee
{{ block.height }} - - - {{ block.extras.pool.name }} +
+ + {{ block.tx_count | number }} -
-
 
-
-
+
+ Mined + Full RBF + RBF