display channel close forensics results

This commit is contained in:
Mononaut 2022-11-10 18:32:18 -06:00 committed by softsimon
parent cf89ded14d
commit 0c96a11150
No known key found for this signature in database
GPG Key ID: 488D7DCFB5A430D7
8 changed files with 134 additions and 2 deletions

View File

@ -217,8 +217,8 @@ export interface IChannel {
updated_at: string; updated_at: string;
created: string; created: string;
status: number; status: number;
node_left: Node, node_left: INode,
node_right: Node, node_right: INode,
} }
@ -236,4 +236,6 @@ export interface INode {
updated_at: string; updated_at: string;
longitude: number; longitude: number;
latitude: number; latitude: number;
funding_balance?: number;
closing_balance?: number;
} }

View File

@ -0,0 +1,19 @@
<div class="box">
<table class="table table-borderless table-striped">
<tbody>
<tr></tr>
<tr>
<td i18n="lightning.starting-balance|Channel starting balance">Starting balance</td>
<td *ngIf="showStartingBalance && minStartingBalance === maxStartingBalance"><app-sats [satoshis]="minStartingBalance"></app-sats></td>
<td *ngIf="showStartingBalance && minStartingBalance !== maxStartingBalance">{{ minStartingBalance | number : '1.0-0' }} - {{ maxStartingBalance | number : '1.0-0' }}<app-sats [valueOverride]=" "></app-sats></td>
<td *ngIf="!showStartingBalance">?</td>
</tr>
<tr>
<td i18n="lightning.closing-balance|Channel closing balance">Closing balance</td>
<td *ngIf="showClosingBalance && minClosingBalance === maxClosingBalance"><app-sats [satoshis]="minClosingBalance"></app-sats></td>
<td *ngIf="showClosingBalance && minClosingBalance !== maxClosingBalance">{{ minClosingBalance | number : '1.0-0' }} - {{ maxClosingBalance | number : '1.0-0' }}<app-sats [valueOverride]=" "></app-sats></td>
<td *ngIf="!showClosingBalance">?</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,9 @@
.box {
margin-top: 20px;
}
@media (max-width: 768px) {
.box {
margin-bottom: 20px;
}
}

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ChannelCloseBoxComponent } from './channel-close-box.component';
describe('ChannelCloseBoxComponent', () => {
let component: ChannelCloseBoxComponent;
let fixture: ComponentFixture<ChannelCloseBoxComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChannelCloseBoxComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ChannelCloseBoxComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,58 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-channel-close-box',
templateUrl: './channel-close-box.component.html',
styleUrls: ['./channel-close-box.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ChannelCloseBoxComponent implements OnChanges {
@Input() channel: any;
@Input() local: any;
@Input() remote: any;
showStartingBalance: boolean = false;
showClosingBalance: boolean = false;
minStartingBalance: number;
maxStartingBalance: number;
minClosingBalance: number;
maxClosingBalance: number;
constructor() { }
ngOnChanges(changes: SimpleChanges): void {
if (this.channel && this.local && this.remote) {
this.showStartingBalance = (this.local.funding_balance || this.remote.funding_balance) && this.channel.funding_ratio;
this.showClosingBalance = this.local.closing_balance || this.remote.closing_balance;
if (this.channel.single_funded) {
if (this.local.funding_balance) {
this.minStartingBalance = this.channel.capacity;
this.maxStartingBalance = this.channel.capacity;
} else if (this.remote.funding_balance) {
this.minStartingBalance = 0;
this.maxStartingBalance = 0;
}
} else {
this.minStartingBalance = clampRound(0, this.channel.capacity, this.local.funding_balance * this.channel.funding_ratio);
this.maxStartingBalance = clampRound(0, this.channel.capacity, this.channel.capacity - (this.remote.funding_balance * this.channel.funding_ratio));
}
const closingCapacity = this.channel.capacity - this.channel.closing_fee;
this.minClosingBalance = clampRound(0, closingCapacity, this.local.closing_balance);
this.maxClosingBalance = clampRound(0, closingCapacity, closingCapacity - this.remote.closing_balance);
// margin of error to account for 2 x 330 sat anchor outputs
if (Math.abs(this.minClosingBalance - this.maxClosingBalance) <= 660) {
this.maxClosingBalance = this.minClosingBalance;
}
} else {
this.showStartingBalance = false;
this.showClosingBalance = false;
}
}
}
function clampRound(min: number, max: number, value: number): number {
return Math.max(0, Math.min(max, Math.round(value)));
}

View File

@ -48,6 +48,15 @@
<td i18n="lightning.capacity">Capacity</td> <td i18n="lightning.capacity">Capacity</td>
<td><app-sats [satoshis]="channel.capacity"></app-sats><app-fiat [value]="channel.capacity" digitsInfo="1.0-0"></app-fiat></td> <td><app-sats [satoshis]="channel.capacity"></app-sats><app-fiat [value]="channel.capacity" digitsInfo="1.0-0"></app-fiat></td>
</tr> </tr>
<tr *ngIf="channel.closed_by">
<td i18n="lightning.closed_by">Closed by</td>
<td>
<a [routerLink]="['/lightning/node' | relativeUrl, channel.closed_by]" >
<ng-container *ngIf="channel.closed_by === channel.node_left.public_key">{{ channel.node_left.alias }}</ng-container>
<ng-container *ngIf="channel.closed_by === channel.node_right.public_key">{{ channel.node_right.alias }}</ng-container>
</a>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
@ -59,9 +68,11 @@
<div class="row row-cols-1 row-cols-md-2"> <div class="row row-cols-1 row-cols-md-2">
<div class="col"> <div class="col">
<app-channel-box [channel]="channel.node_left"></app-channel-box> <app-channel-box [channel]="channel.node_left"></app-channel-box>
<app-channel-close-box *ngIf="showCloseBoxes(channel)" [channel]="channel" [local]="channel.node_left" [remote]="channel.node_right"></app-channel-close-box>
</div> </div>
<div class="col"> <div class="col">
<app-channel-box [channel]="channel.node_right"></app-channel-box> <app-channel-box [channel]="channel.node_right"></app-channel-box>
<app-channel-close-box *ngIf="showCloseBoxes(channel)" [channel]="channel" [local]="channel.node_right" [remote]="channel.node_left"></app-channel-close-box>
</div> </div>
</div> </div>

View File

@ -78,4 +78,9 @@ export class ChannelComponent implements OnInit {
); );
} }
showCloseBoxes(channel: IChannel): boolean {
return !!(channel.node_left.funding_balance || channel.node_left.closing_balance
|| channel.node_right.funding_balance || channel.node_right.closing_balance);
}
} }

View File

@ -12,6 +12,7 @@ import { ChannelsListComponent } from './channels-list/channels-list.component';
import { ChannelComponent } from './channel/channel.component'; import { ChannelComponent } from './channel/channel.component';
import { LightningWrapperComponent } from './lightning-wrapper/lightning-wrapper.component'; import { LightningWrapperComponent } from './lightning-wrapper/lightning-wrapper.component';
import { ChannelBoxComponent } from './channel/channel-box/channel-box.component'; import { ChannelBoxComponent } from './channel/channel-box/channel-box.component';
import { ChannelCloseBoxComponent } from './channel/channel-close-box/channel-close-box.component';
import { ClosingTypeComponent } from './channel/closing-type/closing-type.component'; import { ClosingTypeComponent } from './channel/closing-type/closing-type.component';
import { LightningStatisticsChartComponent } from './statistics-chart/lightning-statistics-chart.component'; import { LightningStatisticsChartComponent } from './statistics-chart/lightning-statistics-chart.component';
import { NodeStatisticsChartComponent } from './node-statistics-chart/node-statistics-chart.component'; import { NodeStatisticsChartComponent } from './node-statistics-chart/node-statistics-chart.component';
@ -45,6 +46,7 @@ import { GroupComponent } from './group/group.component';
ChannelComponent, ChannelComponent,
LightningWrapperComponent, LightningWrapperComponent,
ChannelBoxComponent, ChannelBoxComponent,
ChannelCloseBoxComponent,
ClosingTypeComponent, ClosingTypeComponent,
LightningStatisticsChartComponent, LightningStatisticsChartComponent,
NodesNetworksChartComponent, NodesNetworksChartComponent,
@ -81,6 +83,7 @@ import { GroupComponent } from './group/group.component';
ChannelComponent, ChannelComponent,
LightningWrapperComponent, LightningWrapperComponent,
ChannelBoxComponent, ChannelBoxComponent,
ChannelCloseBoxComponent,
ClosingTypeComponent, ClosingTypeComponent,
LightningStatisticsChartComponent, LightningStatisticsChartComponent,
NodesNetworksChartComponent, NodesNetworksChartComponent,