diff --git a/backend/src/tasks/lightning/network-sync.service.ts b/backend/src/tasks/lightning/network-sync.service.ts index f15aa0d15..8d6d64d66 100644 --- a/backend/src/tasks/lightning/network-sync.service.ts +++ b/backend/src/tasks/lightning/network-sync.service.ts @@ -83,7 +83,7 @@ class NetworkSyncService { logger.info(`${progress} nodes updated. ${deletedSockets} sockets deleted`); // If a channel if not present in the graph, mark it as inactive - nodesApi.$setNodesInactive(graphNodesPubkeys); + await nodesApi.$setNodesInactive(graphNodesPubkeys); if (config.MAXMIND.ENABLED) { $lookupNodeLocation(); @@ -121,7 +121,7 @@ class NetworkSyncService { logger.info(`${progress} channels updated`); // If a channel if not present in the graph, mark it as inactive - channelsApi.$setChannelsInactive(graphChannelsIds); + await channelsApi.$setChannelsInactive(graphChannelsIds); } catch (e) { logger.err(`Cannot update channel list. Reason: ${(e instanceof Error ? e.message : e)}`); } @@ -285,44 +285,66 @@ class NetworkSyncService { for (const channel of channels) { let reason = 0; // Only Esplora backend can retrieve spent transaction outputs - const outspends = await bitcoinApi.$getOutspends(channel.closing_transaction_id); - const lightningScriptReasons: number[] = []; - for (const outspend of outspends) { - if (outspend.spent && outspend.txid) { - const spendingTx = await bitcoinApi.$getRawTransaction(outspend.txid); - const lightningScript = this.findLightningScript(spendingTx.vin[outspend.vin || 0]); - lightningScriptReasons.push(lightningScript); + try { + let outspends: IEsploraApi.Outspend[] | undefined; + try { + outspends = await bitcoinApi.$getOutspends(channel.closing_transaction_id); + } catch (e) { + logger.err(`Failed to call ${config.ESPLORA.REST_API_URL + '/tx/' + channel.closing_transaction_id + '/outspends'}. Reason ${e instanceof Error ? e.message : e}`); + continue; } - } - if (lightningScriptReasons.length === outspends.length - && lightningScriptReasons.filter((r) => r === 1).length === outspends.length) { - reason = 1; - } else { - const filteredReasons = lightningScriptReasons.filter((r) => r !== 1); - if (filteredReasons.length) { - if (filteredReasons.some((r) => r === 2 || r === 4)) { - reason = 3; - } else { - reason = 2; + const lightningScriptReasons: number[] = []; + for (const outspend of outspends) { + if (outspend.spent && outspend.txid) { + let spendingTx: IEsploraApi.Transaction | undefined; + try { + spendingTx = await bitcoinApi.$getRawTransaction(outspend.txid); + } catch (e) { + logger.err(`Failed to call ${config.ESPLORA.REST_API_URL + '/tx/' + outspend.txid}. Reason ${e instanceof Error ? e.message : e}`); + continue; + } + const lightningScript = this.findLightningScript(spendingTx.vin[outspend.vin || 0]); + lightningScriptReasons.push(lightningScript); } + } + if (lightningScriptReasons.length === outspends.length + && lightningScriptReasons.filter((r) => r === 1).length === outspends.length) { + reason = 1; } else { - /* - We can detect a commitment transaction (force close) by reading Sequence and Locktime - https://github.com/lightning/bolts/blob/master/03-transactions.md#commitment-transaction - */ - const closingTx = await bitcoinApi.$getRawTransaction(channel.closing_transaction_id); - const sequenceHex: string = closingTx.vin[0].sequence.toString(16); - const locktimeHex: string = closingTx.locktime.toString(16); - if (sequenceHex.substring(0, 2) === '80' && locktimeHex.substring(0, 2) === '20') { - reason = 2; // Here we can't be sure if it's a penalty or not + const filteredReasons = lightningScriptReasons.filter((r) => r !== 1); + if (filteredReasons.length) { + if (filteredReasons.some((r) => r === 2 || r === 4)) { + reason = 3; + } else { + reason = 2; + } } else { - reason = 1; + /* + We can detect a commitment transaction (force close) by reading Sequence and Locktime + https://github.com/lightning/bolts/blob/master/03-transactions.md#commitment-transaction + */ + let closingTx: IEsploraApi.Transaction | undefined; + try { + closingTx = await bitcoinApi.$getRawTransaction(channel.closing_transaction_id); + } catch (e) { + logger.err(`Failed to call ${config.ESPLORA.REST_API_URL + '/tx/' + channel.closing_transaction_id}. Reason ${e instanceof Error ? e.message : e}`); + continue; + } + const sequenceHex: string = closingTx.vin[0].sequence.toString(16); + const locktimeHex: string = closingTx.locktime.toString(16); + if (sequenceHex.substring(0, 2) === '80' && locktimeHex.substring(0, 2) === '20') { + reason = 2; // Here we can't be sure if it's a penalty or not + } else { + reason = 1; + } } } - } - if (reason) { - logger.debug('Setting closing reason ' + reason + ' for channel: ' + channel.id + '.'); - await DB.query(`UPDATE channels SET closing_reason = ? WHERE id = ?`, [reason, channel.id]); + if (reason) { + logger.debug('Setting closing reason ' + reason + ' for channel: ' + channel.id + '.'); + await DB.query(`UPDATE channels SET closing_reason = ? WHERE id = ?`, [reason, channel.id]); + } + } catch (e) { + logger.err(`$runClosedChannelsForensics() failed for channel ${channel.short_id}. Reason: ${e instanceof Error ? e.message : e}`); } ++progress; diff --git a/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.scss b/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.scss index 85e7c5e68..d738daa81 100644 --- a/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.scss +++ b/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.scss @@ -1,129 +1,5 @@ - -.main-title { - position: relative; - color: #ffffff91; - margin-top: -13px; - font-size: 10px; - text-transform: uppercase; - font-weight: 500; - text-align: center; - padding-bottom: 3px; -} - .full-container { - padding: 0px 15px; - width: 100%; - /* min-height: 500px; */ - height: calc(100% - 150px); - @media (max-width: 992px) { - height: 100%; - padding-bottom: 100px; - }; + margin-top: 25px; + margin-bottom: 25px; + min-height: 100%; } -/* -.chart { - width: 100%; - height: 100%; - padding-bottom: 20px; - padding-right: 10px; - @media (max-width: 992px) { - padding-bottom: 25px; - } - @media (max-width: 829px) { - padding-bottom: 50px; - } - @media (max-width: 767px) { - padding-bottom: 25px; - } - @media (max-width: 629px) { - padding-bottom: 55px; - } - @media (max-width: 567px) { - padding-bottom: 55px; - } -} -*/ -.chart-widget { - width: 100%; - height: 100%; - max-height: 270px; -} - -.formRadioGroup { - margin-top: 6px; - display: flex; - flex-direction: column; - @media (min-width: 991px) { - position: relative; - top: -65px; - } - @media (min-width: 830px) and (max-width: 991px) { - position: relative; - top: 0px; - } - @media (min-width: 830px) { - flex-direction: row; - float: right; - margin-top: 0px; - } - .btn-sm { - font-size: 9px; - @media (min-width: 830px) { - font-size: 14px; - } - } -} - -.pool-distribution { - min-height: 56px; - display: block; - @media (min-width: 485px) { - display: flex; - flex-direction: row; - } - h5 { - margin-bottom: 10px; - } - .item { - width: 50%; - display: inline-block; - margin: 0px auto 20px; - &:nth-child(2) { - order: 2; - @media (min-width: 485px) { - order: 3; - } - } - &:nth-child(3) { - order: 3; - @media (min-width: 485px) { - order: 2; - display: block; - } - @media (min-width: 768px) { - display: none; - } - @media (min-width: 992px) { - display: block; - } - } - .card-title { - font-size: 1rem; - color: #4a68b9; - } - .card-text { - font-size: 18px; - span { - color: #ffffff66; - font-size: 12px; - } - } - } -} - -.skeleton-loader { - width: 100%; - display: block; - max-width: 80px; - margin: 15px auto 3px; -} \ No newline at end of file diff --git a/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.ts b/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.ts index 962059c9d..6f0721d38 100644 --- a/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.ts +++ b/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.ts @@ -25,7 +25,7 @@ import { ActivatedRoute, ParamMap } from '@angular/router'; export class NodeStatisticsChartComponent implements OnInit { @Input() publicKey: string; @Input() right: number | string = 65; - @Input() left: number | string = 55; + @Input() left: number | string = 45; @Input() widget = false; miningWindowPreference: string; @@ -96,7 +96,7 @@ export class NodeStatisticsChartComponent implements OnInit { ], grid: { top: 30, - bottom: 70, + bottom: 20, right: this.right, left: this.left, }, diff --git a/frontend/src/app/lightning/node/node.component.html b/frontend/src/app/lightning/node/node.component.html index a97707930..12ca8eaa1 100644 --- a/frontend/src/app/lightning/node/node.component.html +++ b/frontend/src/app/lightning/node/node.component.html @@ -119,10 +119,14 @@
- - -

Node history

- +
+
+ +
+
+ +
+

Active channels map

diff --git a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.html b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.html index 7eda48b2b..1da3a4baf 100644 --- a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.html +++ b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.html @@ -1,5 +1,5 @@ -
-
+
+
@@ -8,15 +8,15 @@ (Tor nodes excluded)
-
+
+ +
-
-
- -
-
-
-
+
+
+
+
+
\ No newline at end of file diff --git a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.scss b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.scss index fd93b09c5..d8838a093 100644 --- a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.scss +++ b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.scss @@ -1,3 +1,15 @@ +.map-wrapper { + height: 100%; + + &.widget { + height: 250px; + } + + &.graph { + height: auto; + } +} + .card-header { border-bottom: 0; font-size: 18px; @@ -12,11 +24,6 @@ width: 100%; min-height: 600px; height: calc(100% - 150px); - - @media (max-width: 992px) { - height: 100%; - padding-bottom: 100px; - } } .full-container.nodepage { min-height: 400px; @@ -27,6 +34,7 @@ min-height: 400px; margin-top: 25px; margin-bottom: 25px; + min-height: 100%; } .full-container.widget { height: 250px; @@ -68,21 +76,21 @@ min-height: 600px; } .chart.nodepage { - min-height: 400px; + min-height: 100%; + width: 100%; + height: 100%; + padding-bottom: 0px; } .chart.channelpage { min-height: 400px; } .widget { - width: 90vw; + width: 100%; margin-left: auto; margin-right: auto; height: 250px; -webkit-mask: linear-gradient(0deg, #11131f00 5%, #11131fff 25%); - @media (max-width: 767.98px) { - width: 100vw; - } } .widget > .chart { min-height: 250px; @@ -107,4 +115,4 @@ @media (max-width: 767.98px) { top: 250px; } -} +} \ No newline at end of file diff --git a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts index 09e6a17bc..421190d48 100644 --- a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts +++ b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts @@ -165,7 +165,7 @@ export class NodesChannelsMap implements OnInit { if (this.style === 'nodepage' && thisNodeGPS) { this.center = [thisNodeGPS[0], thisNodeGPS[1]]; - this.zoom = 10; + this.zoom = 5; this.channelWidth = 1; this.channelOpacity = 1; }