< 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: 30_15166811759
Line coverage
92%
Covered lines: 47
Uncovered lines: 4
Coverable lines: 51
Total lines: 131
Line coverage: 92.1%
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
 1using NBitcoin;
 2
 3namespace NLightning.Bolt11.Models.TaggedFields;
 4
 5using Common.Utils;
 6using Constants;
 7using Domain.Models;
 8using Domain.ValueObjects;
 9using Enums;
 10using Interfaces;
 11
 12/// <summary>
 13/// Tagged field for routing information
 14/// </summary>
 15/// <remarks>
 16/// The routing information is a collection of routing information entries.
 17/// Each entry contains the public key of the node, the short channel id, the base fee in msat, the fee proportional mil
 18/// </remarks>
 19/// <seealso cref="ITaggedField"/>
 20internal sealed class RoutingInfoTaggedField : ITaggedField
 21{
 28422    public TaggedFieldTypes Type => TaggedFieldTypes.ROUTING_INFO;
 23623    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.ROUTING_INFO_LENGTH + 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.PubKey.ToBytes(), 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++)
 52        {
 5653            bitWriter.WriteBit(false);
 54        }
 2055    }
 56
 57    /// <inheritdoc/>
 58    public bool IsValid()
 59    {
 4060        foreach (var routingInfo in Value)
 61        {
 1262            if (routingInfo.FeeBaseMsat < 0)
 63            {
 064                return false;
 65            }
 66
 1267            if (routingInfo.FeeProportionalMillionths < 0)
 68            {
 069                return false;
 70            }
 71
 1272            if (routingInfo.CltvExpiryDelta < 0)
 73            {
 074                return false;
 75            }
 76        }
 77
 878        return true;
 079    }
 80
 81    /// <summary>
 82    /// Create a new instance of the <see cref="RoutingInfoTaggedField"/> from a <see cref="BitReader"/>
 83    /// </summary>
 84    /// <param name="bitReader">The bit reader to read from</param>
 85    /// <param name="length">The length of the tagged field</param>
 86    /// <returns>A new instance of the <see cref="RoutingInfoTaggedField"/></returns>
 87    internal static RoutingInfoTaggedField FromBitReader(BitReader bitReader, short length)
 88    {
 889        var l = length * 5;
 890        var bitsReadAcc = 0;
 891        var routingInfos = new RoutingInfoCollection();
 92
 4093        for (var i = 0; i < l && l - bitsReadAcc >= TaggedFieldConstants.ROUTING_INFO_LENGTH; i += TaggedFieldConstants.
 94        {
 1295            var pubkeyBytes = new byte[34];
 1296            bitsReadAcc += bitReader.ReadBits(pubkeyBytes, 264);
 97
 1298            var shortChannelBytes = new byte[9];
 1299            bitsReadAcc += bitReader.ReadBits(shortChannelBytes, 64);
 100
 12101            var feeBaseMsat = bitReader.ReadInt32FromBits(32);
 12102            bitsReadAcc += 32;
 103
 12104            var feeProportionalMillionths = bitReader.ReadInt32FromBits(32);
 12105            bitsReadAcc += 32;
 106
 12107            var minFinalCltvExpiry = bitReader.ReadInt16FromBits(16);
 12108            bitsReadAcc += 16;
 109
 12110            routingInfos.Add(new RoutingInfo(new PubKey(pubkeyBytes[..^1]),
 12111                new ShortChannelId(shortChannelBytes[..^1]),
 12112                feeBaseMsat,
 12113                feeProportionalMillionths,
 12114                minFinalCltvExpiry));
 115        }
 116
 117        // Skip any extra bits since padding is expected
 8118        var extraBitsToSkip = l - bitsReadAcc;
 8119        if (extraBitsToSkip > 0)
 120        {
 8121            bitReader.SkipBits(extraBitsToSkip);
 122        }
 123
 8124        return new RoutingInfoTaggedField(routingInfos);
 125    }
 126
 127    private void OnRoutingInfoCollectionChanged(object? sender, EventArgs e)
 128    {
 4129        Length = (short)((Value.Count * TaggedFieldConstants.ROUTING_INFO_LENGTH + Value.Count * 2) / 5);
 4130    }
 131}