Skip to content

Commit

Permalink
Lightning client Service (#261)
Browse files Browse the repository at this point in the history
* Lightning client Service

* Remove unmockable dependency
  • Loading branch information
RodriFS authored Aug 7, 2023
1 parent dc32259 commit ce9c85f
Show file tree
Hide file tree
Showing 19 changed files with 732 additions and 769 deletions.
63 changes: 19 additions & 44 deletions src/Data/Repositories/ChannelRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@
using NodeGuard.Data.Repositories.Interfaces;
using NodeGuard.Jobs;
using NodeGuard.Helpers;
using NodeGuard.Services;
using Grpc.Core;
using Lnrpc;
using Quartz;
using NodeGuard.Services;
using Quartz;
using Microsoft.EntityFrameworkCore;
using NBitcoin;
using Channel = NodeGuard.Data.Models.Channel;
Expand All @@ -40,20 +38,22 @@ public class ChannelRepository : IChannelRepository
private readonly IChannelOperationRequestRepository _channelOperationRequestRepository;
private readonly ISchedulerFactory _schedulerFactory;
private readonly IMapper _mapper;
private readonly ILightningClientService _lightningClientService;

public ChannelRepository(IRepository<Channel> repository,
ILogger<ChannelRepository> logger,
IDbContextFactory<ApplicationDbContext> dbContextFactory,
IChannelOperationRequestRepository channelOperationRequestRepository, ISchedulerFactory schedulerFactory,
IMapper mapper
)
IMapper mapper,
ILightningClientService lightningClientService)
{
_repository = repository;
_logger = logger;
_dbContextFactory = dbContextFactory;
_channelOperationRequestRepository = channelOperationRequestRepository;
_schedulerFactory = schedulerFactory;
this._mapper = mapper;
_lightningClientService = lightningClientService;
}

public async Task<Channel?> GetById(int id)
Expand All @@ -80,10 +80,10 @@ public async Task<List<Channel>> GetAll()
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.Wallet)
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.DestNode)
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.ChannelOperationRequestPsbts)
.Include(x=> x.LiquidityRules)
.ThenInclude(x=> x.Node)
.Include(x=> x.LiquidityRules)
.ThenInclude(x=> x.Wallet)
.Include(x => x.LiquidityRules)
.ThenInclude(x => x.Node)
.Include(x => x.LiquidityRules)
.ThenInclude(x => x.Wallet)
.ToListAsync();
}

Expand Down Expand Up @@ -193,30 +193,6 @@ public async Task<List<Channel>> GetAll()
return _repository.Update(type, applicationDbContext);
}

public async Task<ListChannelsResponse?> ListChannels(Node node)
{
//This method is here to avoid a circular dependency between the LightningService and the ChannelRepository
ListChannelsResponse? listChannelsResponse = null;
try
{
var client = LightningService.CreateLightningClient(node.Endpoint);
listChannelsResponse = await client.Execute(x => x.ListChannelsAsync(new ListChannelsRequest(),
new Metadata
{
{
"macaroon", node.ChannelAdminMacaroon
}
}, null, default));
}
catch (Exception e)
{
_logger.LogError(e, "Error while listing channels for node {NodeId}", node.Id);
return null;
}

return listChannelsResponse;
}

public async Task<List<Channel>> GetAllManagedByUserNodes(string loggedUserId)
{
if (string.IsNullOrWhiteSpace(loggedUserId))
Expand All @@ -225,16 +201,16 @@ public async Task<List<Channel>> GetAllManagedByUserNodes(string loggedUserId)
await using var applicationDbContext = await _dbContextFactory.CreateDbContextAsync();

var channels = applicationDbContext.Channels
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.SourceNode).ThenInclude(x=> x.Users)
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.DestNode).ThenInclude(x=> x.Users)
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.SourceNode).ThenInclude(x => x.Users)
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.DestNode).ThenInclude(x => x.Users)
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.Wallet)
.Include(channel => channel.ChannelOperationRequests).ThenInclude(request => request.ChannelOperationRequestPsbts)
.Include(x=> x.SourceNode)
.Include(x=>x.DestinationNode)
.Include(x=> x.LiquidityRules)
.ThenInclude(x=> x.Node)
.Include(x=> x.LiquidityRules)
.ThenInclude(x=> x.Wallet).AsSplitQuery()
.Include(x => x.SourceNode)
.Include(x => x.DestinationNode)
.Include(x => x.LiquidityRules)
.ThenInclude(x => x.Node)
.Include(x => x.LiquidityRules)
.ThenInclude(x => x.Wallet).AsSplitQuery()
.Where(x => x.SourceNode.Users.Select(user => user.Id).Contains(loggedUserId) ||
x.DestinationNode.Users.Select(user => user.Id).Contains(loggedUserId)).ToList();

Expand All @@ -255,7 +231,7 @@ public async Task<List<Channel>> GetAllManagedByUserNodes(string loggedUserId)
return (false, "No channel operation request found");
}

var channels = await ListChannels(channelOperationRequest.SourceNode);
var channels = await _lightningClientService.ListChannels(channelOperationRequest.SourceNode);

if (channels == null)
{
Expand All @@ -276,7 +252,6 @@ public async Task<List<Channel>> GetAllManagedByUserNodes(string loggedUserId)
var markAsClosed = _repository.Update(channel, applicationDbContext);

return markAsClosed;

}
}
}
16 changes: 3 additions & 13 deletions src/Data/Repositories/Interfaces/IChannelRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,14 @@
*
*/

using NodeGuard.Data.Models;
using Lnrpc;
using Channel = NodeGuard.Data.Models.Channel;

namespace NodeGuard.Data.Repositories.Interfaces;

public interface IChannelRepository
{
Task<Channel?> GetById(int id);

Task<Channel?> GetByChanId(ulong chanId);

Task<List<Channel>> GetAll();
Expand All @@ -42,24 +40,16 @@ public interface IChannelRepository
(bool, string?) RemoveRange(List<Channel> types);

(bool, string?) Update(Channel type);

/// <summary>
/// Marks the channel if it does not exist as closed
/// </summary>
/// <param name="channel"></param>
/// <returns></returns>
Task<(bool, string?)> MarkAsClosed(Channel channel);


/// <summary>
/// List the channels of a node
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
Task<ListChannelsResponse?> ListChannels(Node node);

/// <summary>
/// Retrieves all the channels to/from nodes managed by the user
/// Retrieves all the channels to/from nodes managed by the user
/// </summary>
/// <param name="loggedUserId"></param>
/// <returns></returns>
Expand Down
17 changes: 5 additions & 12 deletions src/Jobs/ChannelMonitorJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
using NodeGuard.Data.Repositories.Interfaces;
using NodeGuard.Services;
using Google.Protobuf;
using Grpc.Core;
using Lnrpc;
using Microsoft.EntityFrameworkCore;
using Quartz;
Expand All @@ -41,15 +40,15 @@ public class ChannelMonitorJob : IJob
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
private readonly INodeRepository _nodeRepository;
private readonly ILightningService _lightningService;
private readonly ILightningClientsStorageService _lightningClientsStorageService;
private readonly ILightningClientService _lightningClientService;

public ChannelMonitorJob(ILogger<ChannelMonitorJob> logger, IDbContextFactory<ApplicationDbContext> dbContextFactory, INodeRepository nodeRepository, ILightningService lightningService, ILightningClientsStorageService lightningClientsStorageService)
public ChannelMonitorJob(ILogger<ChannelMonitorJob> logger, IDbContextFactory<ApplicationDbContext> dbContextFactory, INodeRepository nodeRepository, ILightningService lightningService, ILightningClientService lightningClientService)
{
_logger = logger;
_dbContextFactory = dbContextFactory;
_nodeRepository = nodeRepository;
_lightningService = lightningService;
_lightningClientsStorageService = lightningClientsStorageService;
_lightningClientService = lightningClientService;
}

public async Task Execute(IJobExecutionContext context)
Expand All @@ -67,12 +66,7 @@ public async Task Execute(IJobExecutionContext context)
return;
}

var client = _lightningClientsStorageService.GetLightningClient(node1.Endpoint);
var result = client.ListChannels(new ListChannelsRequest(),
new Metadata
{
{ "macaroon", node1.ChannelAdminMacaroon }
});
var result = await _lightningClientService.ListChannels(node1);

foreach (var channel in result?.Channels)
{
Expand All @@ -82,7 +76,6 @@ public async Task Execute(IJobExecutionContext context)
await RecoverGhostChannels(node1, node2, channel);
await RecoverChannelInConfirmationPendingStatus(node1);
}

}
catch (Exception e)
{
Expand Down Expand Up @@ -113,7 +106,7 @@ public async Task RecoverGhostChannels(Node source, Node destination, Channel ch
OutputIndex = Convert.ToUInt32(outputIndex)
};

var createdChannel = await LightningService.CreateChannel(source, destination.Id, parsedChannelPoint, channel.Capacity, channel.CloseAddress);
var createdChannel = await _lightningService.CreateChannel(source, destination.Id, parsedChannelPoint, channel.Capacity, channel.CloseAddress);
createdChannel.CreatedByNodeGuard = false;

await dbContext.Channels.AddAsync(createdChannel);
Expand Down
16 changes: 6 additions & 10 deletions src/Jobs/NodeChannelSubscribeJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ public class NodeChannelSuscribeJob : IJob
private readonly ILightningService _lightningService;
private readonly INodeRepository _nodeRepository;
private readonly IChannelRepository _channelRepository;
private readonly ILightningClientsStorageService _lightningClientsStorageService;
private readonly ILightningClientService _lightningClientService;

public NodeChannelSuscribeJob(ILogger<NodeChannelSuscribeJob> logger, ILightningService lightningService, INodeRepository nodeRepository, IChannelRepository channelRepository, ILightningClientsStorageService lightningClientsStorageService)
public NodeChannelSuscribeJob(ILogger<NodeChannelSuscribeJob> logger, ILightningService lightningService, INodeRepository nodeRepository, IChannelRepository channelRepository, ILightningClientService lightningClientService)
{
_logger = logger;
_lightningService = lightningService;
_nodeRepository = nodeRepository;
_channelRepository = channelRepository;
_lightningClientsStorageService = lightningClientsStorageService;
_lightningClientService = lightningClientService;
}

public async Task Execute(IJobExecutionContext context)
Expand All @@ -64,11 +64,7 @@ public async Task Execute(IJobExecutionContext context)
return;
}

var client = _lightningClientsStorageService.GetLightningClient(node.Endpoint);
var result = client.SubscribeChannelEvents(new ChannelEventSubscription(),
new Metadata {
{"macaroon", node.ChannelAdminMacaroon}
});
var result = _lightningClientService.SubscribeChannelEvents(node);

while (await result.ResponseStream.MoveNext())
{
Expand All @@ -80,7 +76,8 @@ public async Task Execute(IJobExecutionContext context)
return;
}

try {
try
{
var channelEventUpdate = result.ResponseStream.Current;
_logger.LogInformation("Channel event update received for node {@NodeId}", node.Id);
NodeUpdateManagement(channelEventUpdate, node);
Expand All @@ -91,7 +88,6 @@ public async Task Execute(IJobExecutionContext context)
throw new JobExecutionException(e, true);
}
}

}
catch (Exception e)
{
Expand Down
2 changes: 0 additions & 2 deletions src/Jobs/ProcessNodeChannelAcceptorJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@
using Grpc.Core;
using Grpc.Net.Client;
using Lnrpc;
using NBXplorer;
using NBXplorer.DerivationStrategy;
using Quartz;
using Unmockable;

namespace NodeGuard.Jobs;

Expand Down
8 changes: 3 additions & 5 deletions src/Jobs/SweepNodeWalletsJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@
using Grpc.Core;
using Grpc.Net.Client;
using Lnrpc;
using NBXplorer;
using NBXplorer.DerivationStrategy;
using Quartz;
using Unmockable;

namespace NodeGuard.Jobs;

Expand Down Expand Up @@ -59,7 +57,7 @@ public async Task Execute(IJobExecutionContext context)
_logger.LogInformation("Starting {JobName}... on node: {NodeId}", nameof(SweepNodeWalletsJob), managedNodeId);

var requiredAnchorChannelClosingAmount = Constants.ANCHOR_CLOSINGS_MINIMUM_SATS;



#region Local functions
Expand All @@ -74,7 +72,7 @@ async Task SweepFunds(Node node, Wallet wallet, Lightning.LightningClient lightn
var returningAddress = await _nbXplorerService.GetUnusedAsync(wallet.GetDerivationStrategy(),
DerivationFeature.Deposit,
0,
false, //Reserve is false since this is a cron job and we wan't to avoid massive reserves
false, //Reserve is false since this is a cron job and we wan't to avoid massive reserves
default);

if (node.ChannelAdminMacaroon != null)
Expand Down Expand Up @@ -151,7 +149,7 @@ async Task SweepFunds(Node node, Wallet wallet, Lightning.LightningClient lightn
await context.Scheduler.DeleteJob(context.JobDetail.Key, context.CancellationToken);
return;
}

var loggerFactory = GRPCLoggerFactoryHelper.LoggerFactory();

try
Expand Down
2 changes: 0 additions & 2 deletions src/NodeGuard.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@
<PackageReference Include="Blazorise.SpinKit" Version="1.2.4" />
<PackageReference Include="RestSharp" Version="106.13.0" />
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
<PackageReference Include="Unmockable" Version="3.0.132" />
<PackageReference Include="Unmockable.Wrap" Version="3.0.132" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 1 addition & 2 deletions src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public static void Main(string[] args)
builder.Services.AddTransient<IRemoteSignerService, RemoteSignerServiceService>();
builder.Services.AddTransient<ILiquidityRuleRepository, LiquidityRuleRepository>();
builder.Services.AddTransient<ICoinSelectionService, CoinSelectionService>();
builder.Services.AddSingleton<ILightningClientsStorageService, LightningClientsStorageService>();
builder.Services.AddSingleton<ILightningClientService, LightningClientService>();

//BlazoredToast
builder.Services.AddBlazoredToast();
Expand Down Expand Up @@ -284,7 +284,6 @@ public static void Main(string[] args)
.AddEntityFrameworkCoreInstrumentation()
.AddQuartzInstrumentation()
);

}


Expand Down
Loading

0 comments on commit ce9c85f

Please sign in to comment.