diff --git a/backend/src/api/lightning/clightning/clightning-convert.ts b/backend/src/api/lightning/clightning/clightning-convert.ts index 6fe93df93..b3f59c702 100644 --- a/backend/src/api/lightning/clightning/clightning-convert.ts +++ b/backend/src/api/lightning/clightning/clightning-convert.ts @@ -1,100 +1,11 @@ import { ILightningApi } from '../lightning-api.interface'; +import { FeaturesMap } from '../features'; import FundingTxFetcher from '../../../tasks/lightning/sync-tasks/funding-tx-fetcher'; import logger from '../../../logger'; import { Common } from '../../common'; import { hex2bin } from '../../../utils/format'; import config from '../../../config'; -// https://github.com/lightningnetwork/lnd/blob/master/lnwire/features.go -export enum FeatureBits { - DataLossProtectRequired = 0, - DataLossProtectOptional = 1, - InitialRoutingSync = 3, - UpfrontShutdownScriptRequired = 4, - UpfrontShutdownScriptOptional = 5, - GossipQueriesRequired = 6, - GossipQueriesOptional = 7, - TLVOnionPayloadRequired = 8, - TLVOnionPayloadOptional = 9, - StaticRemoteKeyRequired = 12, - StaticRemoteKeyOptional = 13, - PaymentAddrRequired = 14, - PaymentAddrOptional = 15, - MPPRequired = 16, - MPPOptional = 17, - WumboChannelsRequired = 18, - WumboChannelsOptional = 19, - AnchorsRequired = 20, - AnchorsOptional = 21, - AnchorsZeroFeeHtlcTxRequired = 22, - AnchorsZeroFeeHtlcTxOptional = 23, - ShutdownAnySegwitRequired = 26, - ShutdownAnySegwitOptional = 27, - AMPRequired = 30, - AMPOptional = 31, - ExplicitChannelTypeRequired = 44, - ExplicitChannelTypeOptional = 45, - ScidAliasRequired = 46, - ScidAliasOptional = 47, - PaymentMetadataRequired = 48, - PaymentMetadataOptional = 49, - ZeroConfRequired = 50, - ZeroConfOptional = 51, - KeysendRequired = 54, - KeysendOptional = 55, - ScriptEnforcedLeaseRequired = 2022, - ScriptEnforcedLeaseOptional = 2023, - SimpleTaprootChannelsRequiredFinal = 80, - SimpleTaprootChannelsOptionalFinal = 81, - SimpleTaprootChannelsRequiredStaging = 180, - SimpleTaprootChannelsOptionalStaging = 181, - MaxBolt11Feature = 5114, -}; - -export const FeaturesMap = new Map([ - [FeatureBits.DataLossProtectRequired, 'data-loss-protect'], - [FeatureBits.DataLossProtectOptional, 'data-loss-protect'], - [FeatureBits.InitialRoutingSync, 'initial-routing-sync'], - [FeatureBits.UpfrontShutdownScriptRequired, 'upfront-shutdown-script'], - [FeatureBits.UpfrontShutdownScriptOptional, 'upfront-shutdown-script'], - [FeatureBits.GossipQueriesRequired, 'gossip-queries'], - [FeatureBits.GossipQueriesOptional, 'gossip-queries'], - [FeatureBits.TLVOnionPayloadRequired, 'tlv-onion'], - [FeatureBits.TLVOnionPayloadOptional, 'tlv-onion'], - [FeatureBits.StaticRemoteKeyOptional, 'static-remote-key'], - [FeatureBits.StaticRemoteKeyRequired, 'static-remote-key'], - [FeatureBits.PaymentAddrOptional, 'payment-addr'], - [FeatureBits.PaymentAddrRequired, 'payment-addr'], - [FeatureBits.MPPOptional, 'multi-path-payments'], - [FeatureBits.MPPRequired, 'multi-path-payments'], - [FeatureBits.AnchorsRequired, 'anchor-commitments'], - [FeatureBits.AnchorsOptional, 'anchor-commitments'], - [FeatureBits.AnchorsZeroFeeHtlcTxRequired, 'anchors-zero-fee-htlc-tx'], - [FeatureBits.AnchorsZeroFeeHtlcTxOptional, 'anchors-zero-fee-htlc-tx'], - [FeatureBits.WumboChannelsRequired, 'wumbo-channels'], - [FeatureBits.WumboChannelsOptional, 'wumbo-channels'], - [FeatureBits.AMPRequired, 'amp'], - [FeatureBits.AMPOptional, 'amp'], - [FeatureBits.PaymentMetadataOptional, 'payment-metadata'], - [FeatureBits.PaymentMetadataRequired, 'payment-metadata'], - [FeatureBits.ExplicitChannelTypeOptional, 'explicit-commitment-type'], - [FeatureBits.ExplicitChannelTypeRequired, 'explicit-commitment-type'], - [FeatureBits.KeysendOptional, 'keysend'], - [FeatureBits.KeysendRequired, 'keysend'], - [FeatureBits.ScriptEnforcedLeaseRequired, 'script-enforced-lease'], - [FeatureBits.ScriptEnforcedLeaseOptional, 'script-enforced-lease'], - [FeatureBits.ScidAliasRequired, 'scid-alias'], - [FeatureBits.ScidAliasOptional, 'scid-alias'], - [FeatureBits.ZeroConfRequired, 'zero-conf'], - [FeatureBits.ZeroConfOptional, 'zero-conf'], - [FeatureBits.ShutdownAnySegwitRequired, 'shutdown-any-segwit'], - [FeatureBits.ShutdownAnySegwitOptional, 'shutdown-any-segwit'], - [FeatureBits.SimpleTaprootChannelsRequiredFinal, 'taproot-channels'], - [FeatureBits.SimpleTaprootChannelsOptionalFinal, 'taproot-channels'], - [FeatureBits.SimpleTaprootChannelsRequiredStaging, 'taproot-channels-staging'], - [FeatureBits.SimpleTaprootChannelsOptionalStaging, 'taproot-channels-staging'], -]); - /** * Convert a clightning "listnode" entry to a lnd node entry */ diff --git a/backend/src/api/lightning/features.ts b/backend/src/api/lightning/features.ts new file mode 100644 index 000000000..c0ae6bc96 --- /dev/null +++ b/backend/src/api/lightning/features.ts @@ -0,0 +1,74 @@ +// Lightning feature bit names. +// Sources: https://github.com/lightning/bolts/blob/master/09-features.md +// https://github.com/lightning/blips/blob/master/blip-0002.md +export const FeaturesMap = new Map([ + [0, 'data-loss-protect'], + [1, 'data-loss-protect'], + [3, 'initial-routing-sync'], + [4, 'upfront-shutdown-script'], + [5, 'upfront-shutdown-script'], + [6, 'gossip-queries'], + [7, 'gossip-queries'], + [8, 'tlv-onion'], + [9, 'tlv-onion'], + [10, 'gossip-queries-ex'], + [11, 'gossip-queries-ex'], + [12, 'static-remote-key'], + [13, 'static-remote-key'], + [14, 'payment-addr'], + [15, 'payment-addr'], + [16, 'multi-path-payments'], + [17, 'multi-path-payments'], + [18, 'wumbo-channels'], + [19, 'wumbo-channels'], + [20, 'anchor-commitments'], + [21, 'anchor-commitments'], + [22, 'anchors-zero-fee-htlc-tx'], + [23, 'anchors-zero-fee-htlc-tx'], + [24, 'route-blinding'], + [25, 'route-blinding'], + [26, 'shutdown-any-segwit'], + [27, 'shutdown-any-segwit'], + [28, 'dual-fund'], + [29, 'dual-fund'], + [30, 'amp'], + [31, 'amp'], + [34, 'quiescence'], + [35, 'quiescence'], + [36, 'attribution-data'], + [37, 'attribution-data'], + [38, 'onion-messages'], + [39, 'onion-messages'], + [42, 'provide-storage'], + [43, 'provide-storage'], + [44, 'explicit-commitment-type'], + [45, 'explicit-commitment-type'], + [46, 'scid-alias'], + [47, 'scid-alias'], + [48, 'payment-metadata'], + [49, 'payment-metadata'], + [50, 'zero-conf'], + [51, 'zero-conf'], + [54, 'keysend'], + [55, 'keysend'], + [60, 'simple-close'], + [61, 'simple-close'], + [62, 'splice'], + [63, 'splice'], + [80, 'taproot-channels'], + [81, 'taproot-channels'], + [180, 'taproot-channels-staging'], + [181, 'taproot-channels-staging'], + [256, 'hosted-channels'], + [257, 'hosted-channels'], + [258, 'dns-resolver'], + [259, 'dns-resolver'], + [260, 'htlc-endorsement'], + [261, 'htlc-endorsement'], + [262, 'bolt11-blinded-path'], + [263, 'bolt11-blinded-path'], + [728, 'option-supports-lsps'], + [729, 'option-supports-lsps'], + [2022, 'script-enforced-lease'], + [2023, 'script-enforced-lease'], +]); diff --git a/backend/src/api/lightning/lnd/lnd-api.ts b/backend/src/api/lightning/lnd/lnd-api.ts index 5c3495032..ccff6383b 100644 --- a/backend/src/api/lightning/lnd/lnd-api.ts +++ b/backend/src/api/lightning/lnd/lnd-api.ts @@ -3,6 +3,7 @@ import { Agent } from 'https'; import * as fs from 'fs'; import { AbstractLightningApi } from '../lightning-api-abstract-factory'; import { ILightningApi } from '../lightning-api.interface'; +import { FeaturesMap } from '../features'; import config from '../../../config'; import logger from '../../../logger'; @@ -48,11 +49,17 @@ class LndApi implements AbstractLightningApi { for (const node of graph.nodes) { const nodeFeatures: ILightningApi.Feature[] = []; for (const bit in node.features) { + const f = node.features[bit]; + const bitNum = parseInt(bit, 10); + const lndName = f.name; + const sharedName = FeaturesMap.get(bitNum); + const finalName = f.is_known ? lndName : (sharedName ?? lndName); + const isKnown = f.is_known || !!sharedName; nodeFeatures.push({ - bit: parseInt(bit, 10), - name: node.features[bit].name, - is_required: node.features[bit].is_required, - is_known: node.features[bit].is_known, + bit: bitNum, + name: finalName, + is_required: f.is_required, + is_known: isKnown, }); } node.features = nodeFeatures; diff --git a/contributors/tnull.txt b/contributors/tnull.txt new file mode 100644 index 000000000..00230f372 --- /dev/null +++ b/contributors/tnull.txt @@ -0,0 +1,3 @@ +I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of April 24, 2026. + +Signed: tnull