< Summary - Combined Code Coverage

Information
Class: NLightning.Bolt11.Models.TaggedFields.RoutingInfoTaggedField
Assembly: NLightning.Bolt11.Blazor
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Bolt11/Models/TaggedFields/RoutingInfoTaggedField.cs
Tag: 49_19945309242
Line coverage
0%
Covered lines: 0
Uncovered lines: 56
Coverable lines: 56
Total lines: 133
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 22
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Type()100%210%
get_Value()100%210%
get_Length()100%210%
.ctor(...)100%210%
WriteToBitWriter(...)0%2040%
IsValid()0%7280%
FromBitReader(...)0%110100%
OnRoutingInfoCollectionChanged(...)100%210%

File(s)

/home/runner/work/nlightning/nlightning/src/NLightning.Bolt11/Models/TaggedFields/RoutingInfoTaggedField.cs

#LineLine coverage
 1namespace NLightning.Bolt11.Models.TaggedFields;
 2
 3using Constants;
 4using Domain.Channels.ValueObjects;
 5using Domain.Crypto.ValueObjects;
 6using Domain.Models;
 7using Domain.Utils;
 8using Enums;
 9using Interfaces;
 10
 11/// <summary>
 12/// Tagged field for routing information
 13/// </summary>
 14/// <remarks>
 15/// The routing information is a collection of routing information entries.
 16/// Each entry contains the public key of the node, the short channel id, the base fee in msat, the fee proportional
 17/// millionths, and the cltv expiry delta.
 18/// </remarks>
 19/// <seealso cref="ITaggedField"/>
 20internal sealed class RoutingInfoTaggedField : ITaggedField
 21{
 022    public TaggedFieldTypes Type => TaggedFieldTypes.RoutingInfo;
 023    internal RoutingInfoCollection Value { get; }
 024    public short Length { get; private set; }
 25
 26    /// <summary>
 27    /// Initializes a new instance of the <see cref="DescriptionHashTaggedField"/> class.
 28    /// </summary>
 29    /// <param name="value">The Description Hash</param>
 030    internal RoutingInfoTaggedField(RoutingInfoCollection value)
 31    {
 032        Value = value;
 033        Length = (short)((value.Count * TaggedFieldConstants.RoutingInfoLength + value.Count * 2) / 5);
 34
 035        Value.Changed += OnRoutingInfoCollectionChanged;
 036    }
 37
 38    /// <inheritdoc/>
 39    public void WriteToBitWriter(BitWriter bitWriter)
 40    {
 41        // Write data
 042        foreach (var routingInfo in Value)
 43        {
 044            bitWriter.WriteBits(routingInfo.CompactPubKey, 264);
 045            bitWriter.WriteBits(routingInfo.ShortChannelId, 64);
 046            bitWriter.WriteInt32AsBits(routingInfo.FeeBaseMsat, 32);
 047            bitWriter.WriteInt32AsBits(routingInfo.FeeProportionalMillionths, 32);
 048            bitWriter.WriteInt16AsBits(routingInfo.CltvExpiryDelta, 16);
 49        }
 50
 051        for (var i = 0; i < Value.Count * 2; i++)
 052            bitWriter.WriteBit(false);
 053    }
 54
 55    /// <inheritdoc/>
 56    public bool IsValid()
 57    {
 058        foreach (var routingInfo in Value)
 59        {
 060            if (routingInfo.FeeBaseMsat < 0)
 061                return false;
 62
 063            if (routingInfo.FeeProportionalMillionths < 0)
 064                return false;
 65
 066            if (routingInfo.CltvExpiryDelta < 0)
 067                return false;
 68        }
 69
 070        return true;
 071    }
 72
 73    /// <summary>
 74    /// Create a new instance of the <see cref="RoutingInfoTaggedField"/> from a <see cref="BitReader"/>
 75    /// </summary>
 76    /// <param name="bitReader">The bit reader to read from</param>
 77    /// <param name="length">The length of the tagged field</param>
 78    /// <returns>
 79    /// A new instance of the <see cref="RoutingInfoTaggedField"/> if routing information is present;
 80    /// otherwise, <c>null</c>.
 81    /// </returns>
 82    internal static RoutingInfoTaggedField? FromBitReader(BitReader bitReader, short length)
 83    {
 084        var l = length * 5;
 085        var bitsReadAcc = 0;
 086        var routingInfos = new RoutingInfoCollection();
 87
 88        // Check if there's enough data for the r field
 089        if (l >= TaggedFieldConstants.RoutingInfoLength)
 90        {
 091            for (var i = 0;
 092                 i < l && l - bitsReadAcc >= TaggedFieldConstants.RoutingInfoLength;
 093                 i += TaggedFieldConstants.RoutingInfoLength)
 94            {
 095                var pubkeyBytes = new byte[34];
 096                bitsReadAcc += bitReader.ReadBits(pubkeyBytes, 264);
 97
 098                var shortChannelBytes = new byte[9];
 099                bitsReadAcc += bitReader.ReadBits(shortChannelBytes, 64);
 100
 0101                var feeBaseMsat = bitReader.ReadInt32FromBits(32);
 0102                bitsReadAcc += 32;
 103
 0104                var feeProportionalMillionths = bitReader.ReadInt32FromBits(32);
 0105                bitsReadAcc += 32;
 106
 0107                var minFinalCltvExpiry = bitReader.ReadInt16FromBits(16);
 0108                bitsReadAcc += 16;
 109
 0110                routingInfos.Add(new RoutingInfo(new CompactPubKey(pubkeyBytes[..^1]),
 0111                                                 new ShortChannelId(shortChannelBytes[..^1]),
 0112                                                 feeBaseMsat,
 0113                                                 feeProportionalMillionths,
 0114                                                 minFinalCltvExpiry));
 115            }
 116        }
 117
 118        // Skip any extra bits since padding is expected
 0119        var extraBitsToSkip = l - bitsReadAcc;
 0120        if (extraBitsToSkip > 0)
 0121            bitReader.SkipBits(extraBitsToSkip);
 122
 123        // Return null if there's no routing info present
 0124        return routingInfos.Count > 0
 0125                   ? new RoutingInfoTaggedField(routingInfos)
 0126                   : null;
 127    }
 128
 129    private void OnRoutingInfoCollectionChanged(object? sender, EventArgs e)
 130    {
 0131        Length = (short)((Value.Count * TaggedFieldConstants.RoutingInfoLength + Value.Count * 2) / 5);
 0132    }
 133}