< Summary - Combined Code Coverage

Information
Class: NLightning.Application.Channels.Handlers.FundingConfirmedMessageHandler
Assembly: NLightning.Application
File(s): /home/runner/work/NLightning/NLightning/src/NLightning.Application/Channels/Handlers/FundingConfirmedMessageHandler.cs
Tag: 57_24045730253
Line coverage
0%
Covered lines: 0
Uncovered lines: 55
Coverable lines: 55
Total lines: 130
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/FundingConfirmedMessageHandler.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 FundingConfirmedMessageHandler
 16{
 17    private readonly IChannelMemoryRepository _channelMemoryRepository;
 18    private readonly ILightningSigner _lightningSigner;
 19    private readonly ILogger<FundingConfirmedMessageHandler> _logger;
 20    private readonly IMessageFactory _messageFactory;
 21    private readonly IUnitOfWork _uow;
 22
 23    public event EventHandler<IChannelMessage>? OnMessageReady;
 24
 025    public FundingConfirmedMessageHandler(IChannelMemoryRepository channelMemoryRepository,
 026                                          ILightningSigner lightningSigner,
 027                                          ILogger<FundingConfirmedMessageHandler> logger,
 028                                          IMessageFactory messageFactory,
 029                                          IUnitOfWork uow)
 30    {
 031        _channelMemoryRepository = channelMemoryRepository;
 032        _lightningSigner = lightningSigner;
 033        _logger = logger;
 034        _messageFactory = messageFactory;
 035        _uow = uow;
 036    }
 37
 38    public async Task HandleAsync(ChannelModel channel)
 39    {
 40        try
 41        {
 42            // Check if the channel is in the right state
 043            if (channel.State is not (ChannelState.V1FundingSigned
 044                                   or ChannelState.ReadyForThem))
 045                _logger.LogError(
 046                    "Received funding confirmation, but the channel {ChannelId} had a wrong state: {State}",
 047                    channel.ChannelId, Enum.GetName(channel.State));
 48
 049            var mustUseScidAlias = channel.ChannelConfig.UseScidAlias > FeatureSupport.No;
 50
 51            // Create our new per-commitment point
 052            channel.CommitmentNumber.Increment();
 053            var newPerCommitmentPoint =
 054                _lightningSigner.GetPerCommitmentPoint(channel.ChannelId, channel.CommitmentNumber.Value);
 055            channel.LocalKeySet.UpdatePerCommitmentPoint(newPerCommitmentPoint);
 56
 57            // Handle ScidAlias
 058            if (mustUseScidAlias)
 59            {
 60                // Decide how many SCID aliases we need
 061                var scidAliasesCount = RandomNumberGenerator.GetInt32(2, 6); // Randomly choose between 2 and 5
 062                channel.LocalAliases = new List<ShortChannelId>();
 063                for (var i = 0; i < scidAliasesCount; i++)
 64                {
 65                    // Generate a random SCID alias
 066                    var scidAlias = new ShortChannelId(RandomNumberGenerator.GetBytes(ShortChannelId.Length));
 067                    channel.LocalAliases.Add(scidAlias);
 68                }
 69            }
 70
 071            if (channel.State == ChannelState.ReadyForThem)
 72            {
 73                // Valid transition: ReadyForThem -> Open
 074                channel.UpdateState(ChannelState.Open);
 075                await PersistChannelAsync(channel);
 76
 077                _logger.LogInformation("Channel {ChannelId} is now open", channel.ChannelId);
 78
 79                // TODO: Notify application layer that channel is fully open
 80                // TODO: Update routing tables
 81            }
 082            else if (channel.State == ChannelState.V1FundingSigned)
 83            {
 84                // Valid transition: V1FundingSigned -> ReadyForUs
 085                channel.UpdateState(ChannelState.ReadyForUs);
 086                await PersistChannelAsync(channel);
 87
 088                _logger.LogInformation("Funding confirmed for us for channel {ChannelId}",
 089                                       channel.ChannelId);
 90            }
 91
 092            if (channel.LocalAliases is { Count: > 0 })
 93            {
 94                // Create a ChannelReady message with the SCID aliases
 095                foreach (var alias in channel.LocalAliases)
 96                {
 097                    var channelReadyMessage =
 098                        _messageFactory.CreateChannelReadyMessage(channel.ChannelId, newPerCommitmentPoint, alias);
 99
 100                    // Raise the event with the message
 0101                    OnMessageReady?.Invoke(this, channelReadyMessage);
 102                }
 103            }
 104            else
 105            {
 0106                var channelReadyMessage =
 0107                    _messageFactory.CreateChannelReadyMessage(channel.ChannelId, newPerCommitmentPoint,
 0108                                                              channel.ShortChannelId);
 109
 110                // Raise the event with the message
 0111                OnMessageReady?.Invoke(this, channelReadyMessage);
 112            }
 113
 0114            _logger.LogInformation("Channel {ChannelId} funding transaction confirmed", channel.ChannelId);
 0115        }
 0116        catch (Exception ex)
 117        {
 0118            _logger.LogError(ex, "Error handling funding confirmation for channel {ChannelId}", channel.ChannelId);
 0119            throw;
 120        }
 0121    }
 122
 123    private async Task PersistChannelAsync(ChannelModel channel)
 124    {
 0125        _channelMemoryRepository.UpdateChannel(channel);
 0126        await _uow.ChannelDbRepository.UpdateAsync(channel);
 127
 0128        await _uow.SaveChangesAsync();
 0129    }
 130}