From bad73c180553bf830a407dea87556c357ceb7e4e Mon Sep 17 00:00:00 2001 From: Giovanni La Perna Date: Fri, 7 Apr 2023 01:04:23 +0200 Subject: [PATCH 01/13] Create giovannilaperna.txt --- contributors/giovannilaperna.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 contributors/giovannilaperna.txt diff --git a/contributors/giovannilaperna.txt b/contributors/giovannilaperna.txt new file mode 100644 index 000000000..65a9adf54 --- /dev/null +++ b/contributors/giovannilaperna.txt @@ -0,0 +1,3 @@ +I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of April 7, 203. + +Signed: giovannilaperna From 123b853205f22b6f8931bd0cdcbf2f6600d71160 Mon Sep 17 00:00:00 2001 From: Rex Date: Sat, 8 Apr 2023 11:41:34 +0800 Subject: [PATCH 02/13] Add cla --- contributors/nothing0012.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 contributors/nothing0012.txt diff --git a/contributors/nothing0012.txt b/contributors/nothing0012.txt new file mode 100644 index 000000000..e26514d35 --- /dev/null +++ b/contributors/nothing0012.txt @@ -0,0 +1,3 @@ +I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of April 8, 2023. + +Signed: nothing0012 From 71935e29c8cd4453da5538bf395928d49bdc42b7 Mon Sep 17 00:00:00 2001 From: Giovanni La Perna Date: Sat, 8 Apr 2023 11:19:04 +0200 Subject: [PATCH 03/13] Update and rename giovannilaperna.txt to learntheropes.txt change github username --- contributors/{giovannilaperna.txt => learntheropes.txt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename contributors/{giovannilaperna.txt => learntheropes.txt} (86%) diff --git a/contributors/giovannilaperna.txt b/contributors/learntheropes.txt similarity index 86% rename from contributors/giovannilaperna.txt rename to contributors/learntheropes.txt index 65a9adf54..f8d79bf93 100644 --- a/contributors/giovannilaperna.txt +++ b/contributors/learntheropes.txt @@ -1,3 +1,3 @@ I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of April 7, 203. -Signed: giovannilaperna +Signed: learntheropes From 4ba552fe1b36e05576263039347c58f4e6c594e8 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Sun, 9 Jul 2023 01:15:05 -0400 Subject: [PATCH 04/13] Add basic lightning justice page --- backend/src/api/explorer/channels.api.ts | 19 +++++ backend/src/api/explorer/channels.routes.ts | 13 +++ .../transactions-list.component.html | 2 +- .../src/app/interfaces/node-api.interface.ts | 1 + .../justice-list/justice-list.component.html | 79 +++++++++++++++++++ .../justice-list/justice-list.component.scss | 52 ++++++++++++ .../justice-list/justice-list.component.ts | 60 ++++++++++++++ .../app/lightning/lightning-api.service.ts | 8 +- .../src/app/lightning/lightning.module.ts | 3 + .../app/lightning/lightning.routing.module.ts | 5 ++ .../truncate/truncate.component.html | 2 +- .../truncate/truncate.component.scss | 4 + .../components/truncate/truncate.component.ts | 2 + 13 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 frontend/src/app/lightning/justice-list/justice-list.component.html create mode 100644 frontend/src/app/lightning/justice-list/justice-list.component.scss create mode 100644 frontend/src/app/lightning/justice-list/justice-list.component.ts diff --git a/backend/src/api/explorer/channels.api.ts b/backend/src/api/explorer/channels.api.ts index 00d146770..67d775ea3 100644 --- a/backend/src/api/explorer/channels.api.ts +++ b/backend/src/api/explorer/channels.api.ts @@ -117,6 +117,25 @@ class ChannelsApi { } } + public async $getPenaltyClosedChannels(): Promise { + try { + const query = ` + SELECT n1.alias AS alias_left, + n2.alias AS alias_right, + channels.* + FROM channels + LEFT JOIN nodes AS n1 ON n1.public_key = channels.node1_public_key + LEFT JOIN nodes AS n2 ON n2.public_key = channels.node2_public_key + WHERE channels.status = 2 AND channels.closing_reason = 3 + `; + const [rows]: any = await DB.query(query); + return rows; + } catch (e) { + logger.err('$getPenaltyClosedChannels error: ' + (e instanceof Error ? e.message : e)); + throw e; + } + } + public async $getUnresolvedClosedChannels(): Promise { try { const query = `SELECT * FROM channels WHERE status = 2 AND closing_reason = 2 AND closing_resolved = 0 AND closing_transaction_id != ''`; diff --git a/backend/src/api/explorer/channels.routes.ts b/backend/src/api/explorer/channels.routes.ts index 2b7f3fa6d..f28ab2a9d 100644 --- a/backend/src/api/explorer/channels.routes.ts +++ b/backend/src/api/explorer/channels.routes.ts @@ -11,6 +11,7 @@ class ChannelsRoutes { .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels/search/:search', this.$searchChannelsById) .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels/:short_id', this.$getChannel) .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels', this.$getChannelsForNode) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/penalties', this.$getPenaltyClosedChannels) .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels-geo', this.$getAllChannelsGeo) .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels-geo/:publicKey', this.$getAllChannelsGeo) ; @@ -108,6 +109,18 @@ class ChannelsRoutes { } } + private async $getPenaltyClosedChannels(req: Request, res: Response): Promise { + try { + const channels = await channelsApi.$getPenaltyClosedChannels(); + res.header('Pragma', 'public'); + res.header('Cache-control', 'public'); + res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); + res.json(channels); + } catch (e) { + res.status(500).send(e instanceof Error ? e.message : e); + } + } + private async $getAllChannelsGeo(req: Request, res: Response) { try { const style: string = typeof req.query.style === 'string' ? req.query.style : ''; diff --git a/frontend/src/app/components/transactions-list/transactions-list.component.html b/frontend/src/app/components/transactions-list/transactions-list.component.html index c509a799d..d01453aee 100644 --- a/frontend/src/app/components/transactions-list/transactions-list.component.html +++ b/frontend/src/app/components/transactions-list/transactions-list.component.html @@ -73,7 +73,7 @@ {{ vin.prevout.scriptpubkey_type?.toUpperCase() }}
- +
diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts index 68c45b3b2..df4b5de8e 100644 --- a/frontend/src/app/interfaces/node-api.interface.ts +++ b/frontend/src/app/interfaces/node-api.interface.ts @@ -266,6 +266,7 @@ export interface IChannel { closing_transaction_id: string; closing_reason: string; updated_at: string; + closing_date?: string; created: string; status: number; node_left: INode, diff --git a/frontend/src/app/lightning/justice-list/justice-list.component.html b/frontend/src/app/lightning/justice-list/justice-list.component.html new file mode 100644 index 000000000..071c6f7f4 --- /dev/null +++ b/frontend/src/app/lightning/justice-list/justice-list.component.html @@ -0,0 +1,79 @@ + + +
+

Penalties

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
ClosedCapacityNodesChannel ID
+ ‎{{ channel.closing_date | date:'yyyy-MM-dd HH:mm' }} + + + + {{ channel.capacity | amountShortener: 1 }} + sats + + + + + + + {{ channel.short_id }} + + +
+ +
+
+
+ +
+ + + + +
+
Opening transaction
+
+ + +
+ +
+
Closing transaction
   +
+ + +
+ +
+ + + loading... + diff --git a/frontend/src/app/lightning/justice-list/justice-list.component.scss b/frontend/src/app/lightning/justice-list/justice-list.component.scss new file mode 100644 index 000000000..3547c447f --- /dev/null +++ b/frontend/src/app/lightning/justice-list/justice-list.component.scss @@ -0,0 +1,52 @@ +.container-xl { + max-width: 1400px; +} +.container-xl.widget { + padding-right: 0px; + padding-left: 0px; + padding-bottom: 0px; +} + +tr, td, th { + border: 0px; + padding-top: 0.65rem !important; + padding-bottom: 0.7rem !important; +} + +.clear-link { + color: white; +} + +.pool { + width: 15%; + @media (max-width: 575px) { + width: 75%; + } + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 160px; +} +.pool-name { + display: inline-block; + vertical-align: text-top; + text-overflow: ellipsis; + overflow: hidden; +} + +.liquidity { + width: 10%; + @media (max-width: 575px) { + width: 25%; + } +} + +.fiat { + width: 15%; + @media (min-width: 768px) and (max-width: 991px) { + display: none !important; + } + @media (max-width: 575px) { + display: none !important; + } +} diff --git a/frontend/src/app/lightning/justice-list/justice-list.component.ts b/frontend/src/app/lightning/justice-list/justice-list.component.ts new file mode 100644 index 000000000..d48cdb7ea --- /dev/null +++ b/frontend/src/app/lightning/justice-list/justice-list.component.ts @@ -0,0 +1,60 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { map, Observable, of, Subject, Subscription, switchMap, tap, zip } from 'rxjs'; +import { IChannel } from '../../interfaces/node-api.interface'; +import { LightningApiService } from '../lightning-api.service'; +import { Transaction } from '../../interfaces/electrs.interface'; +import { ElectrsApiService } from '../../services/electrs-api.service'; + +@Component({ + selector: 'app-justice-list', + templateUrl: './justice-list.component.html', + styleUrls: ['./justice-list.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class JusticeList implements OnInit, OnDestroy { + justiceChannels$: Observable; + fetchTransactions$: Subject = new Subject(); + transactionsSubscription: Subscription; + transactions: Transaction[]; + expanded: string = null; + loadingTransactions: boolean = true; + + constructor( + private apiService: LightningApiService, + private electrsApiService: ElectrsApiService, + private cd: ChangeDetectorRef, + ) {} + + ngOnInit(): void { + this.justiceChannels$ = this.apiService.getPenaltyClosedChannels$(); + + this.transactionsSubscription = this.fetchTransactions$.pipe( + tap(() => { + this.loadingTransactions = true; + }), + switchMap((channel: IChannel) => { + return zip([ + channel.transaction_id ? this.electrsApiService.getTransaction$(channel.transaction_id) : of(null), + channel.closing_transaction_id ? this.electrsApiService.getTransaction$(channel.closing_transaction_id) : of(null), + ]); + }), + ).subscribe((transactions) => { + this.transactions = transactions; + this.loadingTransactions = false; + this.cd.markForCheck(); + }); + } + + toggleDetails(channel: any): void { + if (this.expanded === channel.short_id) { + this.expanded = null; + } else { + this.expanded = channel.short_id; + this.fetchTransactions$.next(channel); + } + } + + ngOnDestroy(): void { + this.transactionsSubscription.unsubscribe(); + } +} diff --git a/frontend/src/app/lightning/lightning-api.service.ts b/frontend/src/app/lightning/lightning-api.service.ts index 6ea550591..bdcc78f3f 100644 --- a/frontend/src/app/lightning/lightning-api.service.ts +++ b/frontend/src/app/lightning/lightning-api.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; import { StateService } from '../services/state.service'; -import { INodesRanking, IOldestNodes, ITopNodesPerCapacity, ITopNodesPerChannels } from '../interfaces/node-api.interface'; +import { IChannel, INodesRanking, IOldestNodes, ITopNodesPerCapacity, ITopNodesPerChannels } from '../interfaces/node-api.interface'; @Injectable({ providedIn: 'root' @@ -84,6 +84,12 @@ export class LightningApiService { ); } + getPenaltyClosedChannels$(): Observable { + return this.httpClient.get( + this.apiBasePath + '/api/v1/lightning/penalties' + ); + } + getOldestNodes$(): Observable { return this.httpClient.get( this.apiBasePath + '/api/v1/lightning/nodes/rankings/age' diff --git a/frontend/src/app/lightning/lightning.module.ts b/frontend/src/app/lightning/lightning.module.ts index 5d67433c7..0b824ad78 100644 --- a/frontend/src/app/lightning/lightning.module.ts +++ b/frontend/src/app/lightning/lightning.module.ts @@ -29,6 +29,7 @@ import { NodesChannelsMap } from '../lightning/nodes-channels-map/nodes-channels import { NodesRanking } from '../lightning/nodes-ranking/nodes-ranking.component'; import { TopNodesPerChannels } from '../lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component'; import { TopNodesPerCapacity } from '../lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component'; +import { JusticeList } from '../lightning/justice-list/justice-list.component'; import { OldestNodes } from '../lightning/nodes-ranking/oldest-nodes/oldest-nodes.component'; import { NodesRankingsDashboard } from '../lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component'; import { NodeChannels } from '../lightning/nodes-channels/node-channels.component'; @@ -60,6 +61,7 @@ import { GroupComponent } from './group/group.component'; NodesRanking, TopNodesPerChannels, TopNodesPerCapacity, + JusticeList, OldestNodes, NodesRankingsDashboard, NodeChannels, @@ -97,6 +99,7 @@ import { GroupComponent } from './group/group.component'; NodesRanking, TopNodesPerChannels, TopNodesPerCapacity, + JusticeList, OldestNodes, NodesRankingsDashboard, NodeChannels, diff --git a/frontend/src/app/lightning/lightning.routing.module.ts b/frontend/src/app/lightning/lightning.routing.module.ts index 79c3bc297..8b8041181 100644 --- a/frontend/src/app/lightning/lightning.routing.module.ts +++ b/frontend/src/app/lightning/lightning.routing.module.ts @@ -9,6 +9,7 @@ import { NodesPerISP } from './nodes-per-isp/nodes-per-isp.component'; import { NodesRanking } from './nodes-ranking/nodes-ranking.component'; import { NodesRankingsDashboard } from './nodes-rankings-dashboard/nodes-rankings-dashboard.component'; import { GroupComponent } from './group/group.component'; +import { JusticeList } from './justice-list/justice-list.component'; const routes: Routes = [ { @@ -66,6 +67,10 @@ const routes: Routes = [ type: 'oldest' }, }, + { + path: 'penalties', + component: JusticeList, + }, { path: '**', redirectTo: '' diff --git a/frontend/src/app/shared/components/truncate/truncate.component.html b/frontend/src/app/shared/components/truncate/truncate.component.html index 31d1b1b88..94208f3a4 100644 --- a/frontend/src/app/shared/components/truncate/truncate.component.html +++ b/frontend/src/app/shared/components/truncate/truncate.component.html @@ -1,4 +1,4 @@ - + diff --git a/frontend/src/app/shared/components/truncate/truncate.component.scss b/frontend/src/app/shared/components/truncate/truncate.component.scss index ea69e32c3..315ce4e12 100644 --- a/frontend/src/app/shared/components/truncate/truncate.component.scss +++ b/frontend/src/app/shared/components/truncate/truncate.component.scss @@ -23,4 +23,8 @@ flex-shrink: 0; flex-grow: 0; } + + &.inline { + display: inline-flex; + } } \ No newline at end of file diff --git a/frontend/src/app/shared/components/truncate/truncate.component.ts b/frontend/src/app/shared/components/truncate/truncate.component.ts index 9edc6ddb2..0b6d2d8c1 100644 --- a/frontend/src/app/shared/components/truncate/truncate.component.ts +++ b/frontend/src/app/shared/components/truncate/truncate.component.ts @@ -11,6 +11,8 @@ export class TruncateComponent { @Input() link: any = null; @Input() lastChars: number = 4; @Input() maxWidth: number = null; + @Input() inline: boolean = false; + @Input() textAlign: 'start' | 'end' = 'start'; rtl: boolean; constructor( From a372b479b4bb3f1fa37a2bb82d82f3cf746bba6a Mon Sep 17 00:00:00 2001 From: nymkappa <1612910616@pm.me> Date: Sat, 15 Jul 2023 16:26:25 +0900 Subject: [PATCH 05/13] [network selector] improve align --- .../bisq-master-page/bisq-master-page.component.html | 4 ++-- .../liquid-master-page/liquid-master-page.component.html | 4 ++-- .../src/app/components/master-page/master-page.component.html | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/components/bisq-master-page/bisq-master-page.component.html b/frontend/src/app/components/bisq-master-page/bisq-master-page.component.html index c1280efa1..010723125 100644 --- a/frontend/src/app/components/bisq-master-page/bisq-master-page.component.html +++ b/frontend/src/app/components/bisq-master-page/bisq-master-page.component.html @@ -40,8 +40,8 @@