< Summary - Combined Code Coverage

Information
Class: NLightning.Application.Channels.Handlers.FundingConfirmedHandler
Assembly: NLightning.Application
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Application/Channels/Handlers/FundingConfirmedHandler.cs
Tag: 36_15743069263
Line coverage
0%
Covered lines: 0
Uncovered lines: 52
Coverable lines: 52
Total lines: 127
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 24
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
HandleAsync()0%600240%
PersistChannelAsync()100%210%

File(s)

/home/runner/work/nlightning/nlightning/src/NLightning.Application/Channels/Handlers/FundingConfirmedHandler.cs

#LineLine coverage
 1using System.Security.Cryptography;
 2using Microsoft.Extensions.Logging;
 3
 4namespace NLightning.Application.Channels.Handlers;
 5
 6using Domain.Bitcoin.Interfaces;
 7using Domain.Channels.Enums;
 8using Domain.Channels.Interfaces;
 9using Domain.Channels.Models;
 10using Domain.Channels.ValueObjects;
 11using Domain.Enums;
 12using Domain.Persistence.Interfaces;
 13using Domain.Protocol.Interfaces;
 14
 15public class FundingConfirmedHandler
 16{
 17    private readonly IChannelMemoryRepository _channelMemoryRepository;
 18    private readonly ILightningSigner _lightningSigner;
 19    private readonly ILogger<FundingConfirmedHandler> _logger;
 20    private readonly IMessageFactory _messageFactory;
 21    private readonly IUnitOfWork _uow;
 22
 23    public event EventHandler<IChannelMessage>? OnMessageReady;
 24
 025    public FundingConfirmedHandler(IChannelMemoryRepository channelMemoryRepository, ILightningSigner lightningSigner,
 026                                   ILogger<FundingConfirmedHandler> logger, IMessageFactory messageFactory,
 027                                   IUnitOfWork uow)
 28    {
 029        _channelMemoryRepository = channelMemoryRepository;
 030        _lightningSigner = lightningSigner;
 031        _logger = logger;
 032        _messageFactory = messageFactory;
 033        _uow = uow;
 034    }
 35
 36    public async Task HandleAsync(ChannelModel channel)
 37    {
 38        try
 39        {
 40            // Check if the channel is in the right state
 041            if (channel.State is not (ChannelState.V1FundingSigned
 042                                   or ChannelState.ReadyForThem))
 043                _logger.LogError("Received funding confirmation, but channel {ChannelId} had a wrong state: {State}",
 044                                 channel.ChannelId, Enum.GetName(channel.State));
 45
 046            var mustUseScidAlias = channel.ChannelConfig.UseScidAlias > FeatureSupport.No;
 47
 48            // Create our new per-commitment point
 049            channel.CommitmentNumber.Increment();
 050            var newPerCommitmentPoint =
 051                _lightningSigner.GetPerCommitmentPoint(channel.ChannelId, channel.CommitmentNumber.Value);
 052            channel.LocalKeySet.UpdatePerCommitmentPoint(newPerCommitmentPoint);
 53
 54            // Handle ScidAlias
 055            if (mustUseScidAlias)
 56            {
 57                // Decide how many SCID aliases we need
 058                var scidAliasesCount = RandomNumberGenerator.GetInt32(2, 6); // Randomly choose between 2 and 5
 059                channel.LocalAliases = new List<ShortChannelId>();
 060                for (var i = 0; i < scidAliasesCount; i++)
 61                {
 62                    // Generate a random SCID alias
 063                    var scidAlias = new ShortChannelId(RandomNumberGenerator.GetBytes(ShortChannelId.Length));
 064                    channel.LocalAliases.Add(scidAlias);
 65                }
 66            }
 67
 068            if (channel.State == ChannelState.ReadyForThem)
 69            {
 70                // Valid transition: ReadyForThem -> Open
 071                channel.UpdateState(ChannelState.Open);
 072                await PersistChannelAsync(channel);
 73
 074                _logger.LogInformation("Channel {ChannelId} is now open", channel.ChannelId);
 75
 76                // TODO: Notify application layer that channel is fully open
 77                // TODO: Update routing tables
 78            }
 079            else if (channel.State == ChannelState.V1FundingSigned)
 80            {
 81                // Valid transition: V1FundingSigned -> ReadyForUs
 082                channel.UpdateState(ChannelState.ReadyForUs);
 083                await PersistChannelAsync(channel);
 84
 085                _logger.LogInformation("Funding confirmed for us for channel {ChannelId}",
 086                                       channel.ChannelId);
 87            }
 88
 089            if (channel.LocalAliases is { Count: > 0 })
 90            {
 91                // Create a ChannelReady message with the SCID aliases
 092                foreach (var alias in channel.LocalAliases)
 93                {
 094                    var channelReadyMessage =
 095                        _messageFactory.CreateChannelReadyMessage(channel.ChannelId, newPerCommitmentPoint, alias);
 96
 97                    // Raise the event with the message
 098                    OnMessageReady?.Invoke(this, channelReadyMessage);
 99                }
 100            }
 101            else
 102            {
 0103                var channelReadyMessage =
 0104                    _messageFactory.CreateChannelReadyMessage(channel.ChannelId, newPerCommitmentPoint,
 0105                                                              channel.ShortChannelId);
 106
 107                // Raise the event with the message
 0108                OnMessageReady?.Invoke(this, channelReadyMessage);
 109            }
 110
 0111            _logger.LogInformation("Channel {ChannelId} funding transaction confirmed", channel.ChannelId);
 0112        }
 0113        catch (Exception ex)
 114        {
 0115            _logger.LogError(ex, "Error handling funding confirmation for channel {ChannelId}", channel.ChannelId);
 0116            throw;
 117        }
 0118    }
 119
 120    private async Task PersistChannelAsync(ChannelModel channel)
 121    {
 0122        _channelMemoryRepository.UpdateChannel(channel);
 0123        await _uow.ChannelDbRepository.UpdateAsync(channel);
 124
 0125        await _uow.SaveChangesAsync();
 0126    }
 127}