< Summary - Combined Code Coverage

Information
Class: NLightning.Domain.Node.Options.FeatureOptions
Assembly: NLightning.Domain
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Domain/Node/Options/FeatureOptions.cs
Tag: 30_15166811759
Line coverage
95%
Covered lines: 160
Uncovered lines: 7
Coverable lines: 167
Total lines: 377
Line coverage: 95.8%
Branch coverage
62%
Covered branches: 75
Total branches: 120
Branch coverage: 62.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_DataLossProtect()100%11100%
get_InitialRoutingSync()100%11100%
get_UpfrontShutdownScript()100%11100%
get_GossipQueries()100%11100%
get_ExpandedGossipQueries()100%11100%
get_StaticRemoteKey()100%11100%
get_PaymentSecret()100%11100%
get_BasicMpp()100%11100%
get_LargeChannels()100%11100%
get_AnchorOutputs()100%11100%
get_ZeroFeeAnchorTx()100%11100%
get_RouteBlinding()100%11100%
get_BeyondSegwitShutdown()100%11100%
get_DualFund()100%11100%
get_OnionMessages()100%11100%
get_ChannelType()100%11100%
get_ScidAlias()100%11100%
get_PaymentMetadata()100%11100%
get_ZeroConf()100%11100%
get_ChainHashes()100%11100%
get_RemoteAddress()100%210%
GetNodeFeatures()84.21%42.523885.37%
GetInitTlvs()100%22100%
GetNodeOptions(...)51.25%8080100%

File(s)

/home/runner/work/nlightning/nlightning/src/NLightning.Domain/Node/Options/FeatureOptions.cs

#LineLine coverage
 1using System.Net;
 2
 3namespace NLightning.Domain.Node.Options;
 4
 5using Enums;
 6using Protocol.Constants;
 7using Protocol.Models;
 8using Protocol.Tlv;
 9using ValueObjects;
 10
 11public class FeatureOptions
 12{
 13    /// <summary>
 14    /// Enable data loss protection.
 15    /// </summary>
 24816    public FeatureSupport DataLossProtect { get; set; } = FeatureSupport.Compulsory;
 17
 18    /// <summary>
 19    /// Enable initial routing sync.
 20    /// </summary>
 6421    public FeatureSupport InitialRoutingSync { get; set; } = FeatureSupport.No;
 22
 23    /// <summary>
 24    /// Enable upfront shutdown script.
 25    /// </summary>
 24826    public FeatureSupport UpfrontShutdownScript { get; set; } = FeatureSupport.Optional;
 27
 28    /// <summary>
 29    /// Enable gossip queries.
 30    /// </summary>
 24831    public FeatureSupport GossipQueries { get; set; } = FeatureSupport.Optional;
 32
 33    /// <summary>
 34    /// Enable expanded gossip queries.
 35    /// </summary>
 24836    public FeatureSupport ExpandedGossipQueries { get; set; } = FeatureSupport.Optional;
 37
 38    /// <summary>
 39    /// Enable static remote key.
 40    /// </summary>
 24841    public FeatureSupport StaticRemoteKey { get; set; } = FeatureSupport.Compulsory;
 42
 43    /// <summary>
 44    /// Enable payment secret.
 45    /// </summary>
 24846    public FeatureSupport PaymentSecret { get; set; } = FeatureSupport.Compulsory;
 47
 48    /// <summary>
 49    /// Enable basic MPP.
 50    /// </summary>
 24851    public FeatureSupport BasicMpp { get; set; } = FeatureSupport.Optional;
 52
 53    /// <summary>
 54    /// Enable large channels.
 55    /// </summary>
 24856    public FeatureSupport LargeChannels { get; set; } = FeatureSupport.Optional;
 57
 58    /// <summary>
 59    /// Enable anchor outputs.
 60    /// </summary>
 24861    public FeatureSupport AnchorOutputs { get; set; } = FeatureSupport.Optional;
 62
 63    /// <summary>
 64    /// Enable zero fee anchor tx.
 65    /// </summary>
 6466    public FeatureSupport ZeroFeeAnchorTx { get; set; } = FeatureSupport.No;
 67
 68    /// <summary>
 69    /// Enable route blinding.
 70    /// </summary>
 24871    public FeatureSupport RouteBlinding { get; set; } = FeatureSupport.Optional;
 72
 73    /// <summary>
 74    /// Enable beyond segwit shutdown.
 75    /// </summary>
 6476    public FeatureSupport BeyondSegwitShutdown { get; set; } = FeatureSupport.No;
 77
 78    /// <summary>
 79    /// Enable dual fund.
 80    /// </summary>
 24881    public FeatureSupport DualFund { get; set; } = FeatureSupport.Optional;
 82
 83    /// <summary>
 84    /// Enable onion messages.
 85    /// </summary>
 6486    public FeatureSupport OnionMessages { get; set; } = FeatureSupport.No;
 87
 88    /// <summary>
 89    /// Enable channel type.
 90    /// </summary>
 24891    public FeatureSupport ChannelType { get; set; } = FeatureSupport.Optional;
 92
 93    /// <summary>
 94    /// Enable scid alias.
 95    /// </summary>
 24896    public FeatureSupport ScidAlias { get; set; } = FeatureSupport.Optional;
 97
 98    /// <summary>
 99    /// Enable payment metadata.
 100    /// </summary>
 64101    public FeatureSupport PaymentMetadata { get; set; } = FeatureSupport.No;
 102
 103    /// <summary>
 104    /// Enable zero conf.
 105    /// </summary>
 64106    public FeatureSupport ZeroConf { get; set; } = FeatureSupport.No;
 107
 108    /// <summary>
 109    /// The chain hashes of the node.
 110    /// </summary>
 111    /// <remarks>
 112    /// Initialized as Mainnet if not set.
 113    /// </remarks>
 240114    public IEnumerable<ChainHash> ChainHashes { get; set; } = [];
 115
 116    /// <summary>
 117    /// The remote address of the node.
 118    /// </summary>
 119    /// <remarks>
 120    /// This is used to connect to our node.
 121    /// </remarks>
 0122    public IPAddress? RemoteAddress { get; set; } = null;
 123
 124    /// <summary>
 125    /// Get Features set for the node.
 126    /// </summary>
 127    /// <returns>The features set for the node.</returns>
 128    /// <remarks>
 129    /// All features set as Optional.
 130    /// </remarks>
 131    public FeatureSet GetNodeFeatures()
 132    {
 60133        var features = new FeatureSet();
 134
 135        // Set default features
 60136        if (DataLossProtect != FeatureSupport.No)
 137        {
 60138            features.SetFeature(Feature.OptionDataLossProtect, DataLossProtect == FeatureSupport.Compulsory);
 139        }
 140
 60141        if (InitialRoutingSync != FeatureSupport.No)
 142        {
 0143            features.SetFeature(Feature.InitialRoutingSync, InitialRoutingSync == FeatureSupport.Compulsory);
 144        }
 145
 60146        if (UpfrontShutdownScript != FeatureSupport.No)
 147        {
 60148            features.SetFeature(Feature.OptionUpfrontShutdownScript,
 60149                                UpfrontShutdownScript == FeatureSupport.Compulsory);
 150        }
 151
 60152        if (GossipQueries != FeatureSupport.No)
 153        {
 60154            features.SetFeature(Feature.GossipQueries, GossipQueries == FeatureSupport.Compulsory);
 155        }
 156
 60157        if (ExpandedGossipQueries != FeatureSupport.No)
 158        {
 60159            features.SetFeature(Feature.GossipQueriesEx, ExpandedGossipQueries == FeatureSupport.Compulsory);
 160        }
 161
 60162        if (StaticRemoteKey != FeatureSupport.No)
 163        {
 60164            features.SetFeature(Feature.OptionStaticRemoteKey, StaticRemoteKey == FeatureSupport.Compulsory);
 165        }
 166
 60167        if (PaymentSecret != FeatureSupport.No)
 168        {
 60169            features.SetFeature(Feature.PaymentSecret, PaymentSecret == FeatureSupport.Compulsory);
 170        }
 171
 60172        if (BasicMpp != FeatureSupport.No)
 173        {
 60174            features.SetFeature(Feature.BasicMpp, BasicMpp == FeatureSupport.Compulsory);
 175        }
 176
 60177        if (LargeChannels != FeatureSupport.No)
 178        {
 60179            features.SetFeature(Feature.OptionSupportLargeChannel, LargeChannels == FeatureSupport.Compulsory);
 180        }
 181
 60182        if (AnchorOutputs != FeatureSupport.No)
 183        {
 60184            features.SetFeature(Feature.OptionAnchorOutputs, AnchorOutputs == FeatureSupport.Compulsory);
 185        }
 186
 60187        if (ZeroFeeAnchorTx != FeatureSupport.No)
 188        {
 0189            features.SetFeature(Feature.OptionAnchorsZeroFeeHtlcTx, ZeroFeeAnchorTx == FeatureSupport.Compulsory);
 190        }
 191
 60192        if (RouteBlinding != FeatureSupport.No)
 193        {
 60194            features.SetFeature(Feature.OptionRouteBlinding, RouteBlinding == FeatureSupport.Compulsory);
 195        }
 196
 60197        if (BeyondSegwitShutdown != FeatureSupport.No)
 198        {
 0199            features.SetFeature(Feature.OptionShutdownAnySegwit, BeyondSegwitShutdown == FeatureSupport.Compulsory);
 200        }
 201
 60202        if (DualFund != FeatureSupport.No)
 203        {
 60204            features.SetFeature(Feature.OptionDualFund, DualFund == FeatureSupport.Compulsory);
 205        }
 206
 60207        if (OnionMessages != FeatureSupport.No)
 208        {
 0209            features.SetFeature(Feature.OptionOnionMessages, OnionMessages == FeatureSupport.Compulsory);
 210        }
 211
 60212        if (ChannelType != FeatureSupport.No)
 213        {
 60214            features.SetFeature(Feature.OptionChannelType, ChannelType == FeatureSupport.Compulsory);
 215        }
 216
 60217        if (ScidAlias != FeatureSupport.No)
 218        {
 60219            features.SetFeature(Feature.OptionScidAlias, ScidAlias == FeatureSupport.Compulsory);
 220        }
 221
 60222        if (PaymentMetadata != FeatureSupport.No)
 223        {
 0224            features.SetFeature(Feature.OptionPaymentMetadata, PaymentMetadata == FeatureSupport.Compulsory);
 225        }
 226
 60227        if (ZeroConf != FeatureSupport.No)
 228        {
 0229            features.SetFeature(Feature.OptionZeroconf, ZeroConf == FeatureSupport.Compulsory);
 230        }
 231
 60232        return features;
 233    }
 234
 235    /// <summary>
 236    /// Get the Init extension for the node.
 237    /// </summary>
 238    /// <returns>The Init extension for the node.</returns>
 239    /// <remarks>
 240    /// If there are no ChainHashes, Mainnet is used as default.
 241    /// </remarks>
 242    internal NetworksTlv GetInitTlvs()
 243    {
 244        // If there are no ChainHashes, use Mainnet as default
 48245        if (!ChainHashes.Any())
 246        {
 4247            ChainHashes = [ChainConstants.MAIN];
 248        }
 249
 48250        return new NetworksTlv(ChainHashes);
 251
 252        // TODO: Review this when implementing BOLT7
 253        // // If RemoteAddress is set, add it to the extension
 254        // if (RemoteAddress != null)
 255        // {
 256        //     extension.Add(new(new BigSize(3), RemoteAddress.GetAddressBytes()));
 257        // }
 258    }
 259
 260    /// <summary>
 261    /// Get the node options from the features and extension.
 262    /// </summary>
 263    /// <param name="featureSet">The features of the node.</param>
 264    /// <param name="extension">The extension of the node.</param>
 265    /// <returns>The node options.</returns>
 266    public static FeatureOptions GetNodeOptions(FeatureSet featureSet, TlvStream? extension)
 267    {
 4268        var options = new FeatureOptions
 4269        {
 4270            DataLossProtect = featureSet.IsFeatureSet(Feature.OptionDataLossProtect, true)
 4271                ? FeatureSupport.Compulsory
 4272                : featureSet.IsFeatureSet(Feature.OptionDataLossProtect, false)
 4273                    ? FeatureSupport.Optional
 4274                    : FeatureSupport.No,
 4275            InitialRoutingSync = featureSet.IsFeatureSet(Feature.InitialRoutingSync, true)
 4276                ? FeatureSupport.Compulsory
 4277                : featureSet.IsFeatureSet(Feature.InitialRoutingSync, false)
 4278                    ? FeatureSupport.Optional
 4279                    : FeatureSupport.No,
 4280            UpfrontShutdownScript = featureSet.IsFeatureSet(Feature.OptionUpfrontShutdownScript, true)
 4281                ? FeatureSupport.Compulsory
 4282                : featureSet.IsFeatureSet(Feature.OptionUpfrontShutdownScript, false)
 4283                    ? FeatureSupport.Optional
 4284                    : FeatureSupport.No,
 4285            GossipQueries = featureSet.IsFeatureSet(Feature.GossipQueries, true)
 4286                ? FeatureSupport.Compulsory
 4287                : featureSet.IsFeatureSet(Feature.GossipQueries, false)
 4288                    ? FeatureSupport.Optional
 4289                    : FeatureSupport.No,
 4290            ExpandedGossipQueries = featureSet.IsFeatureSet(Feature.GossipQueriesEx, true)
 4291                ? FeatureSupport.Compulsory
 4292                : featureSet.IsFeatureSet(Feature.GossipQueriesEx, false)
 4293                    ? FeatureSupport.Optional
 4294                    : FeatureSupport.No,
 4295            StaticRemoteKey = featureSet.IsFeatureSet(Feature.OptionStaticRemoteKey, true)
 4296                ? FeatureSupport.Compulsory
 4297                : featureSet.IsFeatureSet(Feature.OptionStaticRemoteKey, false)
 4298                    ? FeatureSupport.Optional
 4299                    : FeatureSupport.No,
 4300            PaymentSecret = featureSet.IsFeatureSet(Feature.PaymentSecret, true)
 4301                ? FeatureSupport.Compulsory
 4302                : featureSet.IsFeatureSet(Feature.PaymentSecret, false)
 4303                    ? FeatureSupport.Optional
 4304                    : FeatureSupport.No,
 4305            BasicMpp = featureSet.IsFeatureSet(Feature.BasicMpp, true)
 4306                ? FeatureSupport.Compulsory
 4307                : featureSet.IsFeatureSet(Feature.BasicMpp, false)
 4308                    ? FeatureSupport.Optional
 4309                    : FeatureSupport.No,
 4310            LargeChannels = featureSet.IsFeatureSet(Feature.OptionSupportLargeChannel, true)
 4311                ? FeatureSupport.Compulsory
 4312                : featureSet.IsFeatureSet(Feature.OptionSupportLargeChannel, false)
 4313                    ? FeatureSupport.Optional
 4314                    : FeatureSupport.No,
 4315            AnchorOutputs = featureSet.IsFeatureSet(Feature.OptionAnchorOutputs, true)
 4316                ? FeatureSupport.Compulsory
 4317                : featureSet.IsFeatureSet(Feature.OptionAnchorOutputs, false)
 4318                    ? FeatureSupport.Optional
 4319                    : FeatureSupport.No,
 4320            ZeroFeeAnchorTx = featureSet.IsFeatureSet(Feature.OptionAnchorsZeroFeeHtlcTx, true)
 4321                ? FeatureSupport.Compulsory
 4322                : featureSet.IsFeatureSet(Feature.OptionAnchorsZeroFeeHtlcTx, false)
 4323                    ? FeatureSupport.Optional
 4324                    : FeatureSupport.No,
 4325            RouteBlinding = featureSet.IsFeatureSet(Feature.OptionRouteBlinding, true)
 4326                ? FeatureSupport.Compulsory
 4327                : featureSet.IsFeatureSet(Feature.OptionRouteBlinding, false)
 4328                    ? FeatureSupport.Optional
 4329                    : FeatureSupport.No,
 4330            BeyondSegwitShutdown = featureSet.IsFeatureSet(Feature.OptionShutdownAnySegwit, true)
 4331                ? FeatureSupport.Compulsory
 4332                : featureSet.IsFeatureSet(Feature.OptionShutdownAnySegwit, false)
 4333                    ? FeatureSupport.Optional
 4334                    : FeatureSupport.No,
 4335            DualFund = featureSet.IsFeatureSet(Feature.OptionDualFund, true)
 4336                ? FeatureSupport.Compulsory
 4337                : featureSet.IsFeatureSet(Feature.OptionDualFund, false)
 4338                    ? FeatureSupport.Optional
 4339                    : FeatureSupport.No,
 4340            OnionMessages = featureSet.IsFeatureSet(Feature.OptionOnionMessages, true)
 4341                ? FeatureSupport.Compulsory
 4342                : featureSet.IsFeatureSet(Feature.OptionOnionMessages, false)
 4343                    ? FeatureSupport.Optional
 4344                    : FeatureSupport.No,
 4345            ChannelType = featureSet.IsFeatureSet(Feature.OptionChannelType, true)
 4346                ? FeatureSupport.Compulsory
 4347                : featureSet.IsFeatureSet(Feature.OptionChannelType, false)
 4348                    ? FeatureSupport.Optional
 4349                    : FeatureSupport.No,
 4350            ScidAlias = featureSet.IsFeatureSet(Feature.OptionScidAlias, true)
 4351                ? FeatureSupport.Compulsory
 4352                : featureSet.IsFeatureSet(Feature.OptionScidAlias, false)
 4353                    ? FeatureSupport.Optional
 4354                    : FeatureSupport.No,
 4355            PaymentMetadata = featureSet.IsFeatureSet(Feature.OptionPaymentMetadata, true)
 4356                ? FeatureSupport.Compulsory
 4357                : featureSet.IsFeatureSet(Feature.OptionPaymentMetadata, false)
 4358                    ? FeatureSupport.Optional
 4359                    : FeatureSupport.No,
 4360            ZeroConf = featureSet.IsFeatureSet(Feature.OptionZeroconf, true)
 4361                ? FeatureSupport.Compulsory
 4362                : featureSet.IsFeatureSet(Feature.OptionZeroconf, false)
 4363                    ? FeatureSupport.Optional
 4364                    : FeatureSupport.No
 4365        };
 366
 4367        if (extension?.TryGetTlv(new BigSize(1), out var chainHashes) ?? false)
 368        {
 4369            options.ChainHashes = Enumerable.Range(0, chainHashes!.Value.Length / ChainHash.LENGTH)
 4370                                            .Select(i => new ChainHash(chainHashes.Value.Skip(i * 32).Take(32).ToArray()
 371        }
 372
 373        // TODO: Add network when implementing BOLT7
 374
 4375        return options;
 376    }
 377}