diff --git a/backend/src/api/explorer/nodes.api.ts b/backend/src/api/explorer/nodes.api.ts index dc359f914..40e106345 100644 --- a/backend/src/api/explorer/nodes.api.ts +++ b/backend/src/api/explorer/nodes.api.ts @@ -3,6 +3,7 @@ import DB from '../../database'; import { ResultSetHeader } from 'mysql2'; import { ILightningApi } from '../lightning/lightning-api.interface'; import { ITopNodesPerCapacity, ITopNodesPerChannels } from '../../mempool.interfaces'; +import { bin2hex } from '../../utils/format'; class NodesApi { public async $getWorldNodes(): Promise { @@ -76,8 +77,18 @@ class NodesApi { node.subdivision = JSON.parse(node.subdivision); node.city = JSON.parse(node.city); node.country = JSON.parse(node.country); - + + // 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 const activeChannelsStats: any = await this.$getActiveChannelsStats(public_key); diff --git a/backend/src/api/lightning/clightning/clightning-convert.ts b/backend/src/api/lightning/clightning/clightning-convert.ts index 84510d0fd..771dabcd7 100644 --- a/backend/src/api/lightning/clightning/clightning-convert.ts +++ b/backend/src/api/lightning/clightning/clightning-convert.ts @@ -6,7 +6,7 @@ import { hex2bin } from '../../../utils/format'; import config from '../../../config'; // https://github.com/lightningnetwork/lnd/blob/master/lnwire/features.go -enum FeatureBits { +export enum FeatureBits { DataLossProtectRequired = 0, DataLossProtectOptional = 1, InitialRoutingSync = 3, @@ -47,10 +47,7 @@ enum FeatureBits { MaxBolt11Feature = 5114, }; -// Features is a mapping of known feature bits to a descriptive name. All known -// 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([ +export const FeaturesMap = new Map([ [FeatureBits.DataLossProtectRequired, 'data-loss-protect'], [FeatureBits.DataLossProtectOptional, 'data-loss-protect'], [FeatureBits.InitialRoutingSync, 'initial-routing-sync'], diff --git a/backend/src/api/lightning/lnd/lnd-api.ts b/backend/src/api/lightning/lnd/lnd-api.ts index eb48b5f96..f4099e82b 100644 --- a/backend/src/api/lightning/lnd/lnd-api.ts +++ b/backend/src/api/lightning/lnd/lnd-api.ts @@ -46,10 +46,10 @@ class LndApi implements AbstractLightningApi { for (const node of graph.nodes) { const nodeFeatures: ILightningApi.Feature[] = []; - for (const bit in node.features) { + for (const bit in node.features) { nodeFeatures.push({ bit: parseInt(bit, 10), - name: node.features[bit].name, + name: node.features[bit].name, is_required: node.features[bit].is_required, is_known: node.features[bit].is_known, }); diff --git a/backend/src/utils/format.ts b/backend/src/utils/format.ts index 9017f349f..63dc07ae4 100644 --- a/backend/src/utils/format.ts +++ b/backend/src/utils/format.ts @@ -29,7 +29,7 @@ export function formatBytes(bytes: number, toUnit: string, skipUnit = false): st } // https://stackoverflow.com/a/64235212 -export function hex2bin(hex): string { +export function hex2bin(hex: string): string { if (!hex) { return ''; } @@ -58,5 +58,38 @@ export function hex2bin(hex): string { default: return ''; } } + 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; } \ No newline at end of file diff --git a/frontend/src/app/lightning/node/node.component.html b/frontend/src/app/lightning/node/node.component.html index 2a74a68aa..c3903e915 100644 --- a/frontend/src/app/lightning/node/node.component.html +++ b/frontend/src/app/lightning/node/node.component.html @@ -21,7 +21,6 @@
-
@@ -59,6 +58,9 @@ + + +
Avg channel distance {{ avgDistance | amountShortener: 1 }} km ·{{ kmToMiles(avgDistance) | amountShortener: 1 }} mi
@@ -100,13 +102,26 @@ + + + + + +
- + + Features + + {{ bits }} + + + +