[lightning] start integrating features bits in the node page

This commit is contained in:
nymkappa 2023-07-05 14:00:30 +02:00
parent 4d41d36fe7
commit 556eb65320
No known key found for this signature in database
GPG key ID: E155910B16E8BD04
5 changed files with 67 additions and 11 deletions

View file

@ -3,6 +3,7 @@ import DB from '../../database';
import { ResultSetHeader } from 'mysql2'; import { ResultSetHeader } from 'mysql2';
import { ILightningApi } from '../lightning/lightning-api.interface'; import { ILightningApi } from '../lightning/lightning-api.interface';
import { ITopNodesPerCapacity, ITopNodesPerChannels } from '../../mempool.interfaces'; import { ITopNodesPerCapacity, ITopNodesPerChannels } from '../../mempool.interfaces';
import { bin2hex } from '../../utils/format';
class NodesApi { class NodesApi {
public async $getWorldNodes(): Promise<any> { public async $getWorldNodes(): Promise<any> {
@ -77,7 +78,17 @@ class NodesApi {
node.city = JSON.parse(node.city); node.city = JSON.parse(node.city);
node.country = JSON.parse(node.country); node.country = JSON.parse(node.country);
// Features
node.features = JSON.parse(node.features); node.features = JSON.parse(node.features);
let maxBit = 0;
for (const feature of node.features) {
maxBit = Math.max(maxBit, feature.bit);
}
node.featuresBits = new Array(maxBit + 1).fill(0);
for (const feature of node.features) {
node.featuresBits[feature.bit] = 1;
}
node.featuresBits = bin2hex(node.featuresBits.reverse().join(''));
// Active channels and capacity // Active channels and capacity
const activeChannelsStats: any = await this.$getActiveChannelsStats(public_key); const activeChannelsStats: any = await this.$getActiveChannelsStats(public_key);

View file

@ -6,7 +6,7 @@ import { hex2bin } from '../../../utils/format';
import config from '../../../config'; import config from '../../../config';
// https://github.com/lightningnetwork/lnd/blob/master/lnwire/features.go // https://github.com/lightningnetwork/lnd/blob/master/lnwire/features.go
enum FeatureBits { export enum FeatureBits {
DataLossProtectRequired = 0, DataLossProtectRequired = 0,
DataLossProtectOptional = 1, DataLossProtectOptional = 1,
InitialRoutingSync = 3, InitialRoutingSync = 3,
@ -47,10 +47,7 @@ enum FeatureBits {
MaxBolt11Feature = 5114, MaxBolt11Feature = 5114,
}; };
// Features is a mapping of known feature bits to a descriptive name. All known export const FeaturesMap = new Map<FeatureBits, string>([
// feature bits must be assigned a name in this mapping, and feature bit pairs
// must be assigned together for correct behavior.
const FeaturesMap = new Map<FeatureBits, string>([
[FeatureBits.DataLossProtectRequired, 'data-loss-protect'], [FeatureBits.DataLossProtectRequired, 'data-loss-protect'],
[FeatureBits.DataLossProtectOptional, 'data-loss-protect'], [FeatureBits.DataLossProtectOptional, 'data-loss-protect'],
[FeatureBits.InitialRoutingSync, 'initial-routing-sync'], [FeatureBits.InitialRoutingSync, 'initial-routing-sync'],

View file

@ -29,7 +29,7 @@ export function formatBytes(bytes: number, toUnit: string, skipUnit = false): st
} }
// https://stackoverflow.com/a/64235212 // https://stackoverflow.com/a/64235212
export function hex2bin(hex): string { export function hex2bin(hex: string): string {
if (!hex) { if (!hex) {
return ''; return '';
} }
@ -60,3 +60,36 @@ export function hex2bin(hex): string {
} }
return out; return out;
} }
export function bin2hex(bin: string): string {
if (!bin) {
return '';
}
let out = '';
for (let i = 0; i < bin.length; i += 4) {
const c = bin.substring(i, i + 4);
switch (c) {
case '0000': out += '0'; break;
case '0001': out += '1'; break;
case '0010': out += '2'; break;
case '0011': out += '3'; break;
case '0100': out += '4'; break;
case '0101': out += '5'; break;
case '0110': out += '6'; break;
case '0111': out += '7'; break;
case '1000': out += '8'; break;
case '1001': out += '9'; break;
case '1010': out += 'a'; break;
case '1011': out += 'b'; break;
case '1100': out += 'c'; break;
case '1101': out += 'd'; break;
case '1110': out += 'e'; break;
case '1111': out += 'f'; break;
default: return '';
}
}
return out;
}

View file

@ -21,7 +21,6 @@
</div> </div>
<div class="box" *ngIf="!error"> <div class="box" *ngIf="!error">
<div class="row"> <div class="row">
<div class="col-md"> <div class="col-md">
<table class="table table-borderless table-striped table-fixed"> <table class="table table-borderless table-striped table-fixed">
@ -59,6 +58,9 @@
<td i18n="lightning.avg-distance" class="text-truncate">Avg channel distance</td> <td i18n="lightning.avg-distance" class="text-truncate">Avg channel distance</td>
<td class="direction-ltr">{{ avgDistance | amountShortener: 1 }} <span class="symbol">km</span> <span class="separator">·</span>{{ kmToMiles(avgDistance) | amountShortener: 1 }} <span class="symbol">mi</span></td> <td class="direction-ltr">{{ avgDistance | amountShortener: 1 }} <span class="symbol">km</span> <span class="separator">·</span>{{ kmToMiles(avgDistance) | amountShortener: 1 }} <span class="symbol">mi</span></td>
</tr> </tr>
<tr *ngIf="!node.geolocation" class="d-none d-md-table-row">
<ng-container *ngTemplateOutlet="featurebits;context:{bits: node.featuresBits}"></ng-container>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
@ -100,13 +102,26 @@
</td> </td>
</ng-template> </ng-template>
</tr> </tr>
<tr *ngIf="node.geolocation">
<ng-container *ngTemplateOutlet="featurebits;context:{bits: node.featuresBits}"></ng-container>
</tr>
<tr *ngIf="!node.geolocation" class="d-table-row d-md-none ">
<ng-container *ngTemplateOutlet="featurebits;context:{bits: node.featuresBits}"></ng-container>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
<ng-template #featurebits let-bits="bits">
<td i18n="lightning.features" class="text-truncate label">Features</td>
<td class="d-flex justify-content-between">
<span class="text-truncate w-90">{{ bits }}</span>
<a href="#" class="w-10"></a>
</td>
</ng-template>
<div class="input-group mt-3" *ngIf="!error && node.socketsObject.length"> <div class="input-group mt-3" *ngIf="!error && node.socketsObject.length">
<div class="d-inline-block" ngbDropdown #myDrop="ngbDropdown" <div class="d-inline-block" ngbDropdown #myDrop="ngbDropdown"
*ngIf="node.socketsObject.length > 1; else noDropdown"> *ngIf="node.socketsObject.length > 1; else noDropdown">