mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-10 09:19:24 +01:00
Make LightningListener nullable, fix some NRE
This commit is contained in:
parent
0c78e9e4ac
commit
6193835ea1
1 changed files with 55 additions and 42 deletions
|
@ -1,3 +1,4 @@
|
|||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
@ -38,7 +39,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
private readonly StoreRepository _storeRepository;
|
||||
private readonly PaymentService _paymentService;
|
||||
readonly Channel<string> _CheckInvoices = Channel.CreateUnbounded<string>();
|
||||
Task _CheckingInvoice;
|
||||
Task? _CheckingInvoice;
|
||||
readonly Dictionary<(string, string), LightningInstanceListener> _InstanceListeners = new Dictionary<(string, string), LightningInstanceListener>();
|
||||
|
||||
public LightningListener(EventAggregator aggregator,
|
||||
|
@ -87,12 +88,15 @@ namespace BTCPayServer.Payments.Lightning
|
|||
var invoice = await GetInvoice(invoiceId);
|
||||
foreach (var listenedInvoice in GetListenedInvoices(invoice))
|
||||
{
|
||||
var instanceListenerKey = (listenedInvoice.Network.CryptoCode, GetLightningUrl(listenedInvoice.SupportedPaymentMethod).ToString());
|
||||
var connStr = GetLightningUrl(listenedInvoice.SupportedPaymentMethod);
|
||||
if (connStr is null)
|
||||
continue;
|
||||
var instanceListenerKey = (listenedInvoice.Network.CryptoCode, connStr.ToString());
|
||||
lock (_InstanceListeners)
|
||||
{
|
||||
if (!_InstanceListeners.TryGetValue(instanceListenerKey, out var instanceListener))
|
||||
{
|
||||
instanceListener ??= new LightningInstanceListener(_InvoiceRepository, _Aggregator, lightningClientFactory, listenedInvoice.Network, GetLightningUrl(listenedInvoice.SupportedPaymentMethod), _paymentService, Logs);
|
||||
instanceListener ??= new LightningInstanceListener(_InvoiceRepository, _Aggregator, lightningClientFactory, listenedInvoice.Network, connStr, _paymentService, Logs);
|
||||
_InstanceListeners.TryAdd(instanceListenerKey, instanceListener);
|
||||
}
|
||||
instanceListener.AddListenedInvoice(listenedInvoice);
|
||||
|
@ -143,7 +147,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
.Where(c => new[] { PaymentTypes.LightningLike, LNURLPayPaymentType.Instance }.Contains(c.GetId().PaymentType)))
|
||||
{
|
||||
LightningLikePaymentMethodDetails lightningMethod;
|
||||
LightningSupportedPaymentMethod lightningSupportedMethod;
|
||||
LightningSupportedPaymentMethod? lightningSupportedMethod;
|
||||
switch (paymentMethod.GetPaymentMethodDetails())
|
||||
{
|
||||
case LNURLPayPaymentMethodDetails lnurlPayPaymentMethodDetails:
|
||||
|
@ -167,16 +171,17 @@ namespace BTCPayServer.Payments.Lightning
|
|||
continue;
|
||||
var network = _NetworkProvider.GetNetwork<BTCPayNetwork>(paymentMethod.GetId().CryptoCode);
|
||||
|
||||
listenedInvoices.Add(new ListenedInvoice()
|
||||
{
|
||||
Expiration = invoice.ExpirationTime,
|
||||
Uri = GetLightningUrl(lightningSupportedMethod).BaseUri.AbsoluteUri,
|
||||
PaymentMethodDetails = lightningMethod,
|
||||
SupportedPaymentMethod = lightningSupportedMethod,
|
||||
PaymentMethod = paymentMethod,
|
||||
Network = network,
|
||||
InvoiceId = invoice.Id
|
||||
});
|
||||
var lnUri = GetLightningUrl(lightningSupportedMethod);
|
||||
if (lnUri == null)
|
||||
continue;
|
||||
listenedInvoices.Add(new ListenedInvoice(
|
||||
lnUri.BaseUri,
|
||||
invoice.ExpirationTime,
|
||||
lightningMethod,
|
||||
lightningSupportedMethod,
|
||||
paymentMethod,
|
||||
network,
|
||||
invoice.Id));
|
||||
}
|
||||
return listenedInvoices;
|
||||
}
|
||||
|
@ -262,6 +267,8 @@ namespace BTCPayServer.Payments.Lightning
|
|||
.Where(method => new[] { PaymentTypes.LightningLike, LNURLPayPaymentType.Instance }.Contains(method.GetId().PaymentType))
|
||||
.ToArray();
|
||||
var store = await _storeRepository.FindStore(invoice.StoreId);
|
||||
if (store is null)
|
||||
return;
|
||||
if (paymentMethods.Any())
|
||||
{
|
||||
var logs = new InvoiceLogs();
|
||||
|
@ -334,9 +341,11 @@ namespace BTCPayServer.Payments.Lightning
|
|||
.CreatePaymentMethodDetails(logs, supportedMethod, paymentMethod, store,
|
||||
paymentMethod.Network, prepObj, pmis));
|
||||
|
||||
var instanceListenerKey = (paymentMethod.Network.CryptoCode,
|
||||
GetLightningUrl(supportedMethod).ToString());
|
||||
LightningInstanceListener instanceListener;
|
||||
var connStr = GetLightningUrl(supportedMethod);
|
||||
if (connStr is null)
|
||||
continue;
|
||||
var instanceListenerKey = (paymentMethod.Network.CryptoCode, connStr.ToString());
|
||||
LightningInstanceListener? instanceListener;
|
||||
lock (_InstanceListeners)
|
||||
{
|
||||
_InstanceListeners.TryGetValue(instanceListenerKey, out instanceListener);
|
||||
|
@ -346,16 +355,17 @@ namespace BTCPayServer.Payments.Lightning
|
|||
await _InvoiceRepository.NewPaymentDetails(invoice.Id, newPaymentMethodDetails,
|
||||
paymentMethod.Network);
|
||||
|
||||
instanceListener.AddListenedInvoice(new ListenedInvoice()
|
||||
{
|
||||
Expiration = invoice.ExpirationTime,
|
||||
Uri = GetLightningUrl(supportedMethod).BaseUri.AbsoluteUri,
|
||||
PaymentMethodDetails = newPaymentMethodDetails,
|
||||
SupportedPaymentMethod = supportedMethod,
|
||||
PaymentMethod = paymentMethod,
|
||||
Network = (BTCPayNetwork)paymentMethod.Network,
|
||||
InvoiceId = invoice.Id
|
||||
});
|
||||
var url = GetLightningUrl(supportedMethod);
|
||||
if (url is null)
|
||||
continue;
|
||||
instanceListener.AddListenedInvoice(new ListenedInvoice(
|
||||
url.BaseUri,
|
||||
invoice.ExpirationTime,
|
||||
newPaymentMethodDetails,
|
||||
supportedMethod,
|
||||
paymentMethod,
|
||||
(BTCPayNetwork)paymentMethod.Network,
|
||||
invoice.Id));
|
||||
|
||||
_Aggregator.Publish(new Events.InvoiceNewPaymentDetailsEvent(invoice.Id,
|
||||
newPaymentMethodDetails, paymentMethod.GetId()));
|
||||
|
@ -374,14 +384,14 @@ namespace BTCPayServer.Payments.Lightning
|
|||
|
||||
}
|
||||
|
||||
private LightningConnectionString GetLightningUrl(LightningSupportedPaymentMethod supportedMethod)
|
||||
private LightningConnectionString? GetLightningUrl(LightningSupportedPaymentMethod supportedMethod)
|
||||
{
|
||||
var url = supportedMethod.GetExternalLightningUrl();
|
||||
if (url != null)
|
||||
return url;
|
||||
if (Options.Value.InternalLightningByCryptoCode.TryGetValue(supportedMethod.CryptoCode, out var conn))
|
||||
return conn;
|
||||
throw new InvalidOperationException($"{supportedMethod.CryptoCode}: The internal lightning node is not set up");
|
||||
return null;
|
||||
}
|
||||
|
||||
TimeSpan _PollInterval = TimeSpan.FromMinutes(1.0);
|
||||
|
@ -400,7 +410,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
}
|
||||
}
|
||||
}
|
||||
private Timer _ListenPoller;
|
||||
private Timer? _ListenPoller;
|
||||
|
||||
public IOptions<LightningNetworkOptions> Options { get; }
|
||||
|
||||
|
@ -412,7 +422,8 @@ namespace BTCPayServer.Payments.Lightning
|
|||
_Cts.Cancel();
|
||||
try
|
||||
{
|
||||
await _CheckingInvoice;
|
||||
if (_CheckingInvoice != null)
|
||||
await _CheckingInvoice;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
@ -420,7 +431,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
}
|
||||
try
|
||||
{
|
||||
await Task.WhenAll(_ListeningInstances.Select(c => c.Value.Listening).ToArray());
|
||||
await Task.WhenAll(_ListeningInstances.Select(c => c.Value.Listening).Where(c => c != null).ToArray()!);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
@ -479,7 +490,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
|
||||
public bool Empty => _ListenedInvoices.IsEmpty;
|
||||
public bool IsListening => Listening?.Status is TaskStatus.Running || Listening?.Status is TaskStatus.WaitingForActivation;
|
||||
public Task Listening { get; set; }
|
||||
public Task? Listening { get; set; }
|
||||
public void EnsureListening(CancellationToken cancellation)
|
||||
{
|
||||
if (!IsListening)
|
||||
|
@ -490,7 +501,7 @@ namespace BTCPayServer.Payments.Lightning
|
|||
Listening = Listen(StopListeningCancellationTokenSource.Token);
|
||||
}
|
||||
}
|
||||
public CancellationTokenSource StopListeningCancellationTokenSource;
|
||||
public CancellationTokenSource? StopListeningCancellationTokenSource;
|
||||
async Task Listen(CancellationToken cancellation)
|
||||
{
|
||||
Logs.PayServer.LogInformation($"{_network.CryptoCode} (Lightning): Start listening {ConnectionString.BaseUri}");
|
||||
|
@ -566,6 +577,8 @@ namespace BTCPayServer.Payments.Lightning
|
|||
|
||||
public async Task<bool> AddPayment(LightningInvoice notification, string invoiceId, PaymentType paymentType)
|
||||
{
|
||||
if (notification?.PaidAt is null)
|
||||
return false;
|
||||
var payment = await _paymentService.AddPayment(invoiceId, notification.PaidAt.Value, new LightningLikePaymentData
|
||||
{
|
||||
BOLT11 = notification.BOLT11,
|
||||
|
@ -595,15 +608,15 @@ namespace BTCPayServer.Payments.Lightning
|
|||
}
|
||||
}
|
||||
|
||||
class ListenedInvoice
|
||||
public record ListenedInvoice(
|
||||
Uri Uri,
|
||||
DateTimeOffset Expiration,
|
||||
LightningLikePaymentMethodDetails PaymentMethodDetails,
|
||||
LightningSupportedPaymentMethod SupportedPaymentMethod,
|
||||
PaymentMethod PaymentMethod,
|
||||
BTCPayNetwork Network,
|
||||
string InvoiceId)
|
||||
{
|
||||
public bool IsExpired() { return DateTimeOffset.UtcNow > Expiration; }
|
||||
public DateTimeOffset Expiration { get; set; }
|
||||
public LightningLikePaymentMethodDetails PaymentMethodDetails { get; set; }
|
||||
public LightningSupportedPaymentMethod SupportedPaymentMethod { get; set; }
|
||||
public PaymentMethod PaymentMethod { get; set; }
|
||||
public string Uri { get; internal set; }
|
||||
public BTCPayNetwork Network { get; internal set; }
|
||||
public string InvoiceId { get; internal set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue