< Summary - Combined Code Coverage

Information
Class: NLightning.Bolt11.Models.TaggedFields.RoutingInfoTaggedField
Assembly: NLightning.Bolt11
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Bolt11/Models/TaggedFields/RoutingInfoTaggedField.cs
Tag: 36_15743069263
Line coverage
92%
Covered lines: 49
Uncovered lines: 4
Coverable lines: 53
Total lines: 123
Line coverage: 92.4%
Branch coverage
83%
Covered branches: 15
Total branches: 18
Branch coverage: 83.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Type()100%11100%
get_Value()100%11100%
get_Length()100%11100%
.ctor(...)100%11100%
WriteToBitWriter(...)100%44100%
IsValid()62.5%13.62855.56%
FromBitReader(...)100%66100%
OnRoutingInfoCollectionChanged(...)100%11100%

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{
 31622    public TaggedFieldTypes Type => TaggedFieldTypes.RoutingInfo;
 25223    internal RoutingInfoCollection Value { get; }
 6824    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>
 2430    internal RoutingInfoTaggedField(RoutingInfoCollection value)
 31    {
 2432        Value = value;
 2433        Length = (short)((value.Count * TaggedFieldConstants.RoutingInfoLength + value.Count * 2) / 5);
 34
 2435        Value.Changed += OnRoutingInfoCollectionChanged;
 2436    }
 37
 38    /// <inheritdoc/>
 39    public void WriteToBitWriter(BitWriter bitWriter)
 40    {
 41        // Write data
 9642        foreach (var routingInfo in Value)
 43        {
 2844            bitWriter.WriteBits(routingInfo.CompactPubKey, 264);
 2845            bitWriter.WriteBits(routingInfo.ShortChannelId, 64);
 2846            bitWriter.WriteInt32AsBits(routingInfo.FeeBaseMsat, 32);
 2847            bitWriter.WriteInt32AsBits(routingInfo.FeeProportionalMillionths, 32);
 2848            bitWriter.WriteInt16AsBits(routingInfo.CltvExpiryDelta, 16);
 49        }
 50
 15251        for (var i = 0; i < Value.Count * 2; i++)
 5652            bitWriter.WriteBit(false);
 2053    }
 54
 55    /// <inheritdoc/>
 56    public bool IsValid()
 57    {
 11258        foreach (var routingInfo in Value)
 59        {
 3260            if (routingInfo.FeeBaseMsat < 0)
 061                return false;
 62
 3263            if (routingInfo.FeeProportionalMillionths < 0)
 064                return false;
 65
 3266            if (routingInfo.CltvExpiryDelta < 0)
 067                return false;
 68        }
 69
 2470        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>A new instance of the <see cref="RoutingInfoTaggedField"/></returns>
 79    internal static RoutingInfoTaggedField FromBitReader(BitReader bitReader, short length)
 80    {
 881        var l = length * 5;
 882        var bitsReadAcc = 0;
 883        var routingInfos = new RoutingInfoCollection();
 84
 885        for (var i = 0;
 2086             i < l && l - bitsReadAcc >= TaggedFieldConstants.RoutingInfoLength;
 1287             i += TaggedFieldConstants.RoutingInfoLength)
 88        {
 1289            var pubkeyBytes = new byte[34];
 1290            bitsReadAcc += bitReader.ReadBits(pubkeyBytes, 264);
 91
 1292            var shortChannelBytes = new byte[9];
 1293            bitsReadAcc += bitReader.ReadBits(shortChannelBytes, 64);
 94
 1295            var feeBaseMsat = bitReader.ReadInt32FromBits(32);
 1296            bitsReadAcc += 32;
 97
 1298            var feeProportionalMillionths = bitReader.ReadInt32FromBits(32);
 1299            bitsReadAcc += 32;
 100
 12101            var minFinalCltvExpiry = bitReader.ReadInt16FromBits(16);
 12102            bitsReadAcc += 16;
 103
 12104            routingInfos.Add(new RoutingInfo(new CompactPubKey(pubkeyBytes[..^1]),
 12105                                             new ShortChannelId(shortChannelBytes[..^1]),
 12106                                             feeBaseMsat,
 12107                                             feeProportionalMillionths,
 12108                                             minFinalCltvExpiry));
 109        }
 110
 111        // Skip any extra bits since padding is expected
 8112        var extraBitsToSkip = l - bitsReadAcc;
 8113        if (extraBitsToSkip > 0)
 8114            bitReader.SkipBits(extraBitsToSkip);
 115
 8116        return new RoutingInfoTaggedField(routingInfos);
 117    }
 118
 119    private void OnRoutingInfoCollectionChanged(object? sender, EventArgs e)
 120    {
 4121        Length = (short)((Value.Count * TaggedFieldConstants.RoutingInfoLength + Value.Count * 2) / 5);
 4122    }
 123}