Channel closing with pending htlc & inactive without priority #393 & #410 (#444)

Channel closing with pending htlc & inactive without priority #393 & #410
This commit is contained in:
ShahanaFarooqui 2020-08-23 14:04:53 -04:00 committed by GitHub
parent 18ec1b70fe
commit 4da3b66bc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 111 additions and 40 deletions

File diff suppressed because one or more lines are too long

View file

@ -12,8 +12,8 @@
<link rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="styles.63dd7929168e9fd14a1a.css"></head>
<link rel="stylesheet" href="styles.1268069d095d5cf8e257.css"></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.2641b91157c23d9a9741.js" defer></script><script src="polyfills-es5.2ac0d98b22574ae745b1.js" nomodule defer></script><script src="polyfills.5ae721a6ae5ab597a53d.js" defer></script><script src="main.bac9de7c65f61812af23.js" defer></script></body>
<script src="runtime.1cfb7a3d5c7630696d04.js" defer></script><script src="polyfills-es5.2ac0d98b22574ae745b1.js" nomodule defer></script><script src="polyfills.5ae721a6ae5ab597a53d.js" defer></script><script src="main.bac9de7c65f61812af23.js" defer></script></body>
</html>

View file

@ -1 +1 @@
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,d=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&d.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);d.length;)d.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"9bb271dd8dffd2d994a5",6:"02d8d1e879c0be336222",7:"4a00e92294df28ac9ca1",8:"98795e7ab86361a07d2b"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,d=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&d.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);d.length;)d.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"9bb271dd8dffd2d994a5",6:"02d8d1e879c0be336222",7:"4a00e92294df28ac9ca1",8:"cbebc1d46c4bfbda8693"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -204,6 +204,9 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
}
onChannelClose(channelToClose: Channel) {
if (channelToClose.active) {
this.store.dispatch(new LNDActions.FetchAllChannels()); //To get latest pending htlc status
}
this.store.dispatch(new RTLActions.OpenAlert({width: '70%', data: {
channel: channelToClose,
component: CloseChannelComponent

View file

@ -10,32 +10,42 @@
<form fxLayout="column">
<div fxLayout="column" class="bordered-box my-2 p-2">
<p fxLayoutAlign="start center" class="pb-1 word-break">Closing channel: {{channelToClose.channel_point}}</p>
<div fxLayoutAlign="space-between center">
<mat-form-field fxFlex.gt-sm="48">
<mat-select [(value)]="selTransType" tabindex="1" [disabled]="!channelToClose.active">
<mat-option *ngFor="let transType of transTypes" [value]="transType.id">
{{transType.name}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48" *ngIf="selTransType=='0'">
<input matInput placeholder="Default" disabled>
</mat-form-field>
<mat-form-field fxFlex.gt-sm="48" fxLayoutAlign="start end" *ngIf="selTransType=='1'">
<input matInput [(ngModel)]="blocks" placeholder="Number of Blocks" type="number" name="blocks" step="1"
min="0" required tabindex="2" #blcks="ngModel">
<mat-error *ngIf="!blocks">Number of blocks is required.</mat-error>
</mat-form-field>
<mat-form-field fxFlex.gt-sm="48" fxLayoutAlign="start end" *ngIf="selTransType=='2'">
<input matInput [(ngModel)]="fees" placeholder="Fees (Sats/Byte)"
type="number" name="fees" step="1" min="0" required tabindex="3" #fee="ngModel">
<mat-error *ngIf="!fees">Fees is required.</mat-error>
</mat-form-field>
<div *ngIf="flgPendingHtlcs" fxLayoutAlign="start center">
<p fxFlex="100" fxLayoutAlign="start center" class="color-warn"><mat-icon class="mr-1 icon-small">close</mat-icon>{{errorMsg}}</p>
</div>
<div *ngIf="!flgPendingHtlcs" fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
<div *ngIf="!channelToClose.active" fxFlex="100" class="alert alert-info">
<fa-icon [icon]="faInfoCircle" class="mr-1 alert-icon"></fa-icon>
<span>Force closing an inactive channel uses a pre-defined fee.</span>
</div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center">
<mat-form-field fxFlex.gt-sm="48">
<mat-select [(value)]="selTransType" tabindex="1" [disabled]="!channelToClose.active">
<mat-option *ngFor="let transType of transTypes" [value]="transType.id">
{{transType.name}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48" *ngIf="selTransType=='0'">
<input matInput placeholder="Default" disabled>
</mat-form-field>
<mat-form-field fxFlex.gt-sm="48" fxLayoutAlign="start end" *ngIf="selTransType=='1'">
<input matInput [(ngModel)]="blocks" placeholder="Number of Blocks" type="number" name="blocks" step="1"
min="0" required tabindex="2" #blcks="ngModel">
<mat-error *ngIf="!blocks">Number of blocks is required.</mat-error>
</mat-form-field>
<mat-form-field fxFlex.gt-sm="48" fxLayoutAlign="start end" *ngIf="selTransType=='2'">
<input matInput [(ngModel)]="fees" placeholder="Fees (Sats/Byte)"
type="number" name="fees" step="1" min="0" required tabindex="3" #fee="ngModel">
<mat-error *ngIf="!fees">Fees is required.</mat-error>
</mat-form-field>
</div>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="end center">
<button mat-stroked-button color="primary" type="reset" class="mr-1" (click)="resetData()" tabindex="2" default>Clear</button>
<button mat-flat-button color="primary" type="submit" tabindex="4" (click)="onCloseChannel()">Close Channel</button>
<button *ngIf="channelToClose.active && !flgPendingHtlcs" mat-stroked-button color="primary" type="reset" class="mr-1" (click)="resetData()" tabindex="3" default>Clear</button>
<button *ngIf="!flgPendingHtlcs" mat-flat-button color="primary" type="submit" tabindex="4" (click)="onCloseChannel()">Close Channel</button>
<button *ngIf="flgPendingHtlcs" mat-flat-button color="primary" type="submit" tabindex="5" (click)="onClose()">Ok</button>
</div>
</form>
</mat-card-content>

View file

@ -1,7 +1,12 @@
import { Component, OnInit, Inject } from '@angular/core';
import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { faExclamationTriangle, faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import { LoggerService } from '../../../../shared/services/logger.service';
import { Channel } from '../../../../shared/models/lndModels';
import { ChannelInformation } from '../../../../shared/models/alertData';
import { TRANS_TYPES } from '../../../../shared/services/consts-enums-functions';
@ -15,17 +20,35 @@ import * as fromRTLReducer from '../../../../store/rtl.reducers';
templateUrl: './close-channel.component.html',
styleUrls: ['./close-channel.component.scss']
})
export class CloseChannelComponent implements OnInit {
export class CloseChannelComponent implements OnInit, OnDestroy {
public channelToClose: Channel;
public transTypes = TRANS_TYPES;
public selTransType = '0';
public blocks = null;
public fees = null;
public faExclamationTriangle = faExclamationTriangle;
public faInfoCircle = faInfoCircle;
public flgPendingHtlcs = false;
public errorMsg = 'Please wait for pending HTLCs to settle before attempting channel closure.';
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(public dialogRef: MatDialogRef<CloseChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: ChannelInformation, private store: Store<fromRTLReducer.RTLState>) {}
constructor(public dialogRef: MatDialogRef<CloseChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: ChannelInformation, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions, private logger: LoggerService) {}
ngOnInit() {
this.channelToClose = this.data.channel;
this.actions$.pipe(takeUntil(this.unSubs[0]),
filter(action => action.type === LNDActions.EFFECT_ERROR_LND || action.type === LNDActions.SET_ALL_CHANNELS_LND))
.subscribe((action: LNDActions.EffectError | LNDActions.SetAllChannels) => {
if (action.type === LNDActions.SET_ALL_CHANNELS_LND) {
let filteredChannel = action.payload.find(channel => channel.chan_id === this.data.channel.chan_id);
if (filteredChannel.pending_htlcs && filteredChannel.pending_htlcs.length && filteredChannel.pending_htlcs.length > 0) {
this.flgPendingHtlcs = true;
}
}
if (action.type === LNDActions.EFFECT_ERROR_LND && action.payload.action === 'FetchChannels/all') {
this.logger.error('Fetching latest channel information failed!\n' + action.payload.message);
}
});
}
onCloseChannel() {
@ -48,4 +71,10 @@ export class CloseChannelComponent implements OnInit {
this.dialogRef.close(false);
}
ngOnDestroy() {
this.unSubs.forEach(completeSub => {
completeSub.next();
completeSub.complete();
});
}
}

View file

@ -1038,4 +1038,10 @@ table {
30% {transform: translateY(-20%)}
40% {transform: translateY(20%)}
50% {transform: translateY(0)}
}
}
.mat-form-field-appearance-legacy.mat-form-field-disabled {
& input, mat-select, .mat-select-trigger, .mat-select-value, .mat-select-arro-wrapper, textarea, .mat-form-field-infix {
cursor: not-allowed;
}
}

View file

@ -18,7 +18,7 @@
$background: map-get($theme, background);
$background-color: mat-color($background, card);
$hover-background: rgba(0, 0, 0, 0.04);
$hover-background-white: rgba(255, 255, 255, 0.06);
$hover-background-dark: rgba(255, 255, 255, 0.06);
.bg-primary {
@include _mat-toolbar-color($primary);

View file

@ -18,7 +18,7 @@
$background: map-get($theme, background);
$background-color: mat-color($background, card);
$hover-background: rgba(0, 0, 0, 0.04);
$hover-background-white: rgba(255, 255, 255, 0.06);
$hover-background-dark: rgba(255, 255, 255, 0.06);
&.night {
.mat-primary {
@ -68,7 +68,7 @@
.mat-tree-node:hover, .mat-nested-tree-node-parent:hover, .mat-select-panel .mat-option:hover, .mat-menu-panel .mat-menu-content .mat-menu-item:hover {
color: $primary-darker;
cursor: pointer;
background: $hover-background-white;
background: $hover-background-dark;
& .ng-fa-icon, & .mat-icon {
color: $primary-darker;
}
@ -170,4 +170,16 @@
}
}
& .mat-form-field-disabled {
& .mat-form-field-underline{
background-color: transparent;
background-image: linear-gradient(90deg,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);
background-size: 5px 100%;
height: 1.4px;
}
& .mat-form-field-flex {
background-color: $hover-background-dark;
}
}
}

View file

@ -18,7 +18,7 @@
$background: map-get($theme, background);
$background-color: mat-color($background, card);
$hover-background: rgba(0, 0, 0, 0.04);
$hover-background-white: rgba(255, 255, 255, 0.06);
$hover-background-dark: rgba(255, 255, 255, 0.06);
&.day {
.mat-progress-bar.this-channel-bar .mat-progress-bar-fill::after {
@ -165,4 +165,15 @@
}
}
& .mat-form-field-disabled {
& .mat-form-field-underline{
background-color: transparent;
background-image: linear-gradient(90deg,rgba(0,0,0,.42) 0,rgba(0,0,0,.42) 33%,transparent 0);
background-size: 5px 100%;
height: 1.4px;
}
& .mat-form-field-flex {
background-color: $hover-background;
}
}
}