diff --git a/BTCPayServer/HostedServices/InvoiceWatcher.cs b/BTCPayServer/HostedServices/InvoiceWatcher.cs index 974de48a2..817544699 100644 --- a/BTCPayServer/HostedServices/InvoiceWatcher.cs +++ b/BTCPayServer/HostedServices/InvoiceWatcher.cs @@ -307,7 +307,7 @@ namespace BTCPayServer.HostedServices private async Task WaitPendingInvoices() { - await Task.WhenAll((await _invoiceRepository.GetPendingInvoices()) + await Task.WhenAll((await _invoiceRepository.GetPendingInvoiceIds()) .Select(id => Wait(id)).ToArray()); } diff --git a/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs b/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs index 9e341d324..97b899121 100644 --- a/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs +++ b/BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs @@ -143,7 +143,7 @@ namespace BTCPayServer.Payments.Bitcoin switch (newEvent) { case NBXplorer.Models.NewBlockEvent evt: - await UpdatePaymentStates(wallet, await _InvoiceRepository.GetPendingInvoices()); + await UpdatePaymentStates(wallet); _Aggregator.Publish(new Events.NewBlockEvent() { CryptoCode = evt.CryptoCode }); break; case NBXplorer.Models.NewTransactionEvent evt: @@ -220,9 +220,9 @@ namespace BTCPayServer.Payments.Bitcoin } } - async Task UpdatePaymentStates(BTCPayWallet wallet, string[] invoiceIds) + async Task UpdatePaymentStates(BTCPayWallet wallet) { - var invoices = await _InvoiceRepository.GetInvoices(invoiceIds); + var invoices = await _InvoiceRepository.GetPendingInvoices(skipNoPaymentInvoices: true); await Task.WhenAll(invoices.Select(i => UpdatePaymentStates(wallet, i)).ToArray()); } async Task UpdatePaymentStates(BTCPayWallet wallet, string invoiceId) @@ -234,9 +234,9 @@ namespace BTCPayServer.Payments.Bitcoin } async Task UpdatePaymentStates(BTCPayWallet wallet, InvoiceEntity invoice) { - List updatedPaymentEntities = new List(); var transactions = await wallet.GetTransactions(invoice.GetAllBitcoinPaymentData(false) + .Where(p => p.Network == wallet.Network) .Select(p => p.Outpoint.Hash) .ToArray(), true); bool? originalPJBroadcasted = null; @@ -355,14 +355,12 @@ namespace BTCPayServer.Payments.Bitcoin private async Task FindPaymentViaPolling(BTCPayWallet wallet, BTCPayNetwork network) { int totalPayment = 0; - var invoices = await _InvoiceRepository.GetPendingInvoices(); + var invoices = await _InvoiceRepository.GetPendingInvoices(true); var coinsPerDerivationStrategy = new Dictionary(); - foreach (var invoiceId in invoices) + foreach (var i in invoices) { - var invoice = await _InvoiceRepository.GetInvoice(invoiceId, true); - if (invoice == null) - continue; + var invoice = i; var alreadyAccounted = invoice.GetAllBitcoinPaymentData(false).Select(p => p.Outpoint).ToHashSet(); var strategy = GetDerivationStrategy(invoice, network); if (strategy == null) diff --git a/BTCPayServer/Payments/Lightning/LightningListener.cs b/BTCPayServer/Payments/Lightning/LightningListener.cs index 519aef55c..b16716dac 100644 --- a/BTCPayServer/Payments/Lightning/LightningListener.cs +++ b/BTCPayServer/Payments/Lightning/LightningListener.cs @@ -215,7 +215,7 @@ namespace BTCPayServer.Payments.Lightning { try { - var invoiceIds = await _InvoiceRepository.GetPendingInvoices(); + var invoiceIds = await _InvoiceRepository.GetPendingInvoiceIds(); foreach (var invoiceId in invoiceIds) _CheckInvoices.Writer.TryWrite(invoiceId); } diff --git a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroListener.cs b/BTCPayServer/Services/Altcoins/Monero/Services/MoneroListener.cs index cf3e448f0..897fc0454 100644 --- a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroListener.cs +++ b/BTCPayServer/Services/Altcoins/Monero/Services/MoneroListener.cs @@ -360,16 +360,11 @@ namespace BTCPayServer.Services.Altcoins.Monero.Services private async Task UpdateAnyPendingMoneroLikePayment(string cryptoCode) { - var invoiceIds = await _invoiceRepository.GetPendingInvoices(); - if (!invoiceIds.Any()) - { + var invoices = await _invoiceRepository.GetPendingInvoices(); + if (!invoices.Any()) return; - } - - var invoices = await _invoiceRepository.GetInvoices(new InvoiceQuery() { InvoiceId = invoiceIds }); invoices = invoices.Where(entity => entity.GetPaymentMethod(new PaymentMethodId(cryptoCode, MoneroPaymentType.Instance)) ?.GetPaymentMethodDetails().Activated is true).ToArray(); - _logger.LogInformation($"Updating pending payments for {cryptoCode} in {string.Join(',', invoiceIds)}"); await UpdatePaymentStates(cryptoCode, invoices); } diff --git a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashListener.cs b/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashListener.cs index cb18e3c21..08333161a 100644 --- a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashListener.cs +++ b/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashListener.cs @@ -355,16 +355,11 @@ namespace BTCPayServer.Services.Altcoins.Zcash.Services private async Task UpdateAnyPendingZcashLikePayment(string cryptoCode) { - var invoiceIds = await _invoiceRepository.GetPendingInvoices(); - if (!invoiceIds.Any()) - { + var invoices = await _invoiceRepository.GetPendingInvoices(); + if (!invoices.Any()) return; - } - - var invoices = await _invoiceRepository.GetInvoices(new InvoiceQuery() { InvoiceId = invoiceIds }); invoices = invoices.Where(entity => entity.GetPaymentMethod(new PaymentMethodId(cryptoCode, ZcashPaymentType.Instance)) ?.GetPaymentMethodDetails().Activated is true).ToArray(); - _logger.LogInformation($"Updating pending payments for {cryptoCode} in {string.Join(',', invoiceIds)}"); await UpdatePaymentStates(cryptoCode, invoices); } diff --git a/BTCPayServer/Services/Invoices/InvoiceRepository.cs b/BTCPayServer/Services/Invoices/InvoiceRepository.cs index 20e93536b..31760bb25 100644 --- a/BTCPayServer/Services/Invoices/InvoiceRepository.cs +++ b/BTCPayServer/Services/Invoices/InvoiceRepository.cs @@ -88,7 +88,20 @@ namespace BTCPayServer.Services.Invoices .ToListAsync()).Select(ToEntity); } - public async Task GetPendingInvoices() + public async Task GetPendingInvoices(bool includeAddressData = false, bool skipNoPaymentInvoices = false) + { + using var ctx = _applicationDbContextFactory.CreateContext(); + var q = ctx.PendingInvoices.AsQueryable(); + q = q.Include(o => o.InvoiceData) + .ThenInclude(o => o.Payments); + if (includeAddressData) + q = q.Include(o => o.InvoiceData) + .ThenInclude(o => o.AddressInvoices); + if (skipNoPaymentInvoices) + q = q.Where(i => i.InvoiceData.Payments.Any()); + return (await q.Select(o => o.InvoiceData).ToArrayAsync()).Select(ToEntity).ToArray(); + } + public async Task GetPendingInvoiceIds() { using var ctx = _applicationDbContextFactory.CreateContext(); return await ctx.PendingInvoices.AsQueryable().Select(data => data.Id).ToArrayAsync(); @@ -640,8 +653,16 @@ namespace BTCPayServer.Services.Invoices if (queryObject.InvoiceId != null && queryObject.InvoiceId.Length > 0) { - var statusSet = queryObject.InvoiceId.ToHashSet().ToArray(); - query = query.Where(i => statusSet.Contains(i.Id)); + if (queryObject.InvoiceId.Length > 1) + { + var statusSet = queryObject.InvoiceId.ToHashSet().ToArray(); + query = query.Where(i => statusSet.Contains(i.Id)); + } + else + { + var invoiceId = queryObject.InvoiceId.First(); + query = query.Where(i => i.Id == invoiceId); + } } if (queryObject.StoreId != null && queryObject.StoreId.Length > 0)