diff --git a/src/Jobs/ChannelMonitorJob.cs b/src/Jobs/ChannelMonitorJob.cs index 2be6e69b..96e7c550 100644 --- a/src/Jobs/ChannelMonitorJob.cs +++ b/src/Jobs/ChannelMonitorJob.cs @@ -42,6 +42,8 @@ public class ChannelMonitorJob : IJob private readonly INodeRepository _nodeRepository; private readonly ILightningService _lightningService; private readonly ILightningClientService _lightningClientService; + private readonly Dictionary _remoteNodes = new(); + private readonly HashSet _checkedRemoteNodes = new(); public ChannelMonitorJob(ILogger logger, IDbContextFactory dbContextFactory, INodeRepository nodeRepository, ILightningService lightningService, ILightningClientService lightningClientService) { @@ -67,13 +69,20 @@ public async Task Execute(IJobExecutionContext context) return; } - var result = await _lightningClientService.ListChannels(node1); + var client = _lightningClientService.GetLightningClient(node1.Endpoint); + var result = await _lightningClientService.ListChannels(node1, client); var channels = result?.Channels.ToList(); await MarkClosedChannelsAsClosed(node1, channels); - foreach (var channel in channels) + foreach (var channel in channels ?? new()) { - var node2 = await _nodeRepository.GetOrCreateByPubKey(channel.RemotePubkey, _lightningService); + var node2 = await GetRemoteNode(channel.RemotePubkey); + if (node2 == null) + { + _logger.LogWarning("The external node {NodeId} was set up for monitoring but the remote node {RemoteNodeId} doesn't exist anymore", nodeId, channel.RemotePubkey); + continue; + } + await RefreshExternalNodeData(node1, node2, client); // Recover Operations on channels await RecoverGhostChannels(node1, node2, channel); @@ -89,6 +98,41 @@ public async Task Execute(IJobExecutionContext context) _logger.LogInformation("{JobName} ended", nameof(ChannelMonitorJob)); } + private async Task GetRemoteNode(string pubKey) + { + if (_remoteNodes.TryGetValue(pubKey, out var node)) + { + return node; + } + node = await _nodeRepository.GetOrCreateByPubKey(pubKey, _lightningService); + _remoteNodes.Add(node.PubKey, node); + return node; + } + + private async Task RefreshExternalNodeData(Node managedNode, Node remoteNode, Lightning.LightningClient lightningClient) + { + if (_checkedRemoteNodes.Contains(remoteNode.PubKey)) + { + return; + } + var nodeInfo = await _lightningClientService.GetNodeInfo(managedNode, remoteNode.PubKey, lightningClient); + if (nodeInfo == null) + { + _logger.LogWarning("The external node {NodeId} was set up for monitoring but the remote node {RemoteNodeId} doesn't exist anymore", managedNode.Id, remoteNode.PubKey); + return; + } + + if (remoteNode.Name == nodeInfo.Alias) return; + + remoteNode.Name = nodeInfo.Alias; + var (updated, error) = _nodeRepository.Update(remoteNode); + if (!updated) + { + _logger.LogWarning("Couldn't update Node {NodeId} with Name {Name}: {Error}", remoteNode.Id, remoteNode.Name, error); + } + _checkedRemoteNodes.Add(remoteNode.PubKey); + } + public async Task RecoverGhostChannels(Node source, Node destination, Channel channel) { if (!channel.Initiator && destination.IsManaged) return; diff --git a/src/Jobs/ProcessNodeChannelAcceptorJob.cs b/src/Jobs/ProcessNodeChannelAcceptorJob.cs index 1407a3b1..89a33a83 100644 --- a/src/Jobs/ProcessNodeChannelAcceptorJob.cs +++ b/src/Jobs/ProcessNodeChannelAcceptorJob.cs @@ -39,17 +39,20 @@ public class ProcessNodeChannelAcceptorJob : IJob private readonly IWalletRepository _walletRepository; private readonly INBXplorerService _nBXplorerService; private readonly ILogger _logger; + private readonly ILightningClientService _lightningClientService; public ProcessNodeChannelAcceptorJob(ILogger logger, INodeRepository nodeRepository, IWalletRepository walletRepository, - INBXplorerService nBXplorerService + INBXplorerService nBXplorerService, + ILightningClientService lightningClientService ) { _nodeRepository = nodeRepository; _walletRepository = walletRepository; _nBXplorerService = nBXplorerService; _logger = logger; + _lightningClientService = lightningClientService; } public async Task Execute(IJobExecutionContext context) @@ -126,18 +129,7 @@ await asyncDuplexStreamingCall.RequestStream.WriteAsync(new ChannelAcceptRespons { _logger.LogInformation("Starting {JobName} on node: {NodeName}", nameof(ProcessNodeChannelAcceptorJob), node.Name); - using var grpcChannel = GrpcChannel.ForAddress($"https://{node.Endpoint}", - new GrpcChannelOptions - { - HttpHandler = new HttpClientHandler - { - ServerCertificateCustomValidationCallback = - HttpClientHandler.DangerousAcceptAnyServerCertificateValidator - }, - LoggerFactory = loggerFactory, - }); - - var client = new Lightning.LightningClient(grpcChannel); + var client = _lightningClientService.GetLightningClient(node.Endpoint); if (!string.IsNullOrEmpty(node.ChannelAdminMacaroon)) { diff --git a/src/Services/LightningService.cs b/src/Services/LightningService.cs index 4250191b..de0cc6f4 100644 --- a/src/Services/LightningService.cs +++ b/src/Services/LightningService.cs @@ -1297,6 +1297,13 @@ public async Task> GetChannelsState() foreach (var node in nodes) { var listChannelsResponse = await _lightningClientService.ListChannels(node); + + if (listChannelsResponse == null) + { + _logger.LogError("Error while getting channels for node: {NodeId}", node.Id); + continue; + } + var channels = listChannelsResponse.Channels.ToList(); foreach (var channel in channels)