From d1efddd312c239fd447aad3bf6f4f713847dabed Mon Sep 17 00:00:00 2001 From: Kukks Date: Thu, 24 Sep 2020 12:18:19 +0200 Subject: [PATCH] Make sure lightning listener is listening to new bolt11 invoices for partially paid btcpay invoices and that all payments are registered to the invoice. --- BTCPayServer.Tests/ServerTester.cs | 9 +++++-- BTCPayServer.Tests/UnitTest1.cs | 26 ++++++++++-------- .../Payments/Lightning/LightningListener.cs | 27 ++++++++++++++++--- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/BTCPayServer.Tests/ServerTester.cs b/BTCPayServer.Tests/ServerTester.cs index 7dea97cdf..541c1a4e2 100644 --- a/BTCPayServer.Tests/ServerTester.cs +++ b/BTCPayServer.Tests/ServerTester.cs @@ -140,12 +140,17 @@ namespace BTCPayServer.Tests await CustomerLightningD.Pay(bolt11); } - public async Task WaitForEvent(Func action) + public async Task WaitForEvent(Func action, Func correctEvent = null) { var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var sub = PayTester.GetService().Subscribe(evt => { - tcs.TrySetResult(evt); + if(correctEvent is null) + tcs.TrySetResult(evt); + else if (correctEvent(evt)) + { + tcs.TrySetResult(evt); + } }); await action.Invoke(); var result = await tcs.Task; diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index 271eaa000..36c1b7921 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -762,34 +762,38 @@ namespace BTCPayServer.Tests await user.RegisterDerivationSchemeAsync("BTC"); await user.RegisterLightningNodeAsync("BTC", LightningConnectionType.CLightning); user.SetNetworkFeeMode(NetworkFeeMode.Never); - var invoice = await user.BitPay.CreateInvoiceAsync(new Invoice(0.01m, "BTC")); + await user.ModifyStoreAsync(model => model.SpeedPolicy = SpeedPolicy.HighSpeed); + var invoice = await user.BitPay.CreateInvoiceAsync(new Invoice(0.0001m, "BTC")); await tester.WaitForEvent(async () => { await tester.ExplorerNode.SendToAddressAsync( - BitcoinAddress.Create(invoice.BitcoinAddress, Network.RegTest), Money.Coins(0.005m)); + BitcoinAddress.Create(invoice.BitcoinAddress, Network.RegTest), Money.Coins(0.00005m)); }); - + await tester.ExplorerNode.GenerateAsync(1); var newInvoice = await user.BitPay.GetInvoiceAsync(invoice.Id); var newBolt11 = newInvoice.CryptoInfo.First(o => o.PaymentUrls.BOLT11 != null).PaymentUrls.BOLT11; var oldBolt11= invoice.CryptoInfo.First(o => o.PaymentUrls.BOLT11 != null).PaymentUrls.BOLT11; Assert.NotEqual(newBolt11,oldBolt11); Assert.Equal(newInvoice.BtcDue.GetValue(), BOLT11PaymentRequest.Parse(newBolt11, Network.RegTest).MinimumAmount.ToDecimal(LightMoneyUnit.BTC)); + + Logs.Tester.LogInformation($"Paying invoice {newInvoice.Id} remaining due amount {newInvoice.BtcDue.GetValue()} via lightning" ); var evt = await tester.WaitForEvent(async () => { await tester.SendLightningPaymentAsync(newInvoice); - }); - Assert.Equal(evt.InvoiceId, invoice.Id); - Assert.Equal(InvoiceStatus.Complete, evt.State.Status); - Assert.Equal(InvoiceExceptionStatus.None, evt.State.ExceptionStatus); + }, evt => evt.InvoiceId == invoice.Id); + + var fetchedInvoice = await tester.PayTester.InvoiceRepository.GetInvoice(evt.InvoiceId); + Assert.Contains(fetchedInvoice.Status, new []{InvoiceStatus.Complete, InvoiceStatus.Confirmed}); + Assert.Equal(InvoiceExceptionStatus.None, fetchedInvoice.ExceptionStatus); + Logs.Tester.LogInformation($"Paying invoice {invoice.Id} original full amount bolt11 invoice " ); evt = await tester.WaitForEvent(async () => { await tester.SendLightningPaymentAsync(invoice); - }); - + }, evt => evt.InvoiceId == invoice.Id); Assert.Equal(evt.InvoiceId, invoice.Id); - Assert.Equal(InvoiceStatus.Invalid, evt.State.Status); - Assert.Equal(InvoiceExceptionStatus.PaidOver, evt.State.ExceptionStatus); + fetchedInvoice = await tester.PayTester.InvoiceRepository.GetInvoice(evt.InvoiceId); + Assert.Equal( 3,fetchedInvoice.Payments.Count); } [Fact(Timeout = 60 * 2 * 1000)] diff --git a/BTCPayServer/Payments/Lightning/LightningListener.cs b/BTCPayServer/Payments/Lightning/LightningListener.cs index 1cd2a6fd9..542559dd0 100644 --- a/BTCPayServer/Payments/Lightning/LightningListener.cs +++ b/BTCPayServer/Payments/Lightning/LightningListener.cs @@ -170,11 +170,30 @@ namespace BTCPayServer.Payments.Lightning await _lightningLikePaymentHandler.CreatePaymentMethodDetails( logs, supportedMethod, paymentMethod, store, paymentMethod.Network, prepObj); + + + var instanceListenerKey = (paymentMethod.Network.CryptoCode, + supportedMethod.GetLightningUrl().ToString()); + if (_InstanceListeners.TryGetValue(instanceListenerKey, out var instanceListener)) + { + + await _InvoiceRepository.NewAddress(invoice.Id, newPaymentMethodDetails, + paymentMethod.Network); - await _InvoiceRepository.NewAddress(invoice.Id, newPaymentMethodDetails, - paymentMethod.Network); - - _Aggregator.Publish(new InvoiceNewAddressEvent(invoice.Id, newPaymentMethodDetails.GetPaymentDestination(),paymentMethod.Network )); + instanceListener.AddListenedInvoice(new ListenedInvoice() + { + Expiration = invoice.ExpirationTime, + Uri = supportedMethod.GetLightningUrl().BaseUri.AbsoluteUri, + PaymentMethodDetails = (LightningLikePaymentMethodDetails) newPaymentMethodDetails, + SupportedPaymentMethod = supportedMethod, + PaymentMethod = paymentMethod, + Network = (BTCPayNetwork) paymentMethod.Network, + InvoiceId = invoice.Id + }); + + _Aggregator.Publish(new InvoiceNewAddressEvent(invoice.Id, + newPaymentMethodDetails.GetPaymentDestination(), paymentMethod.Network)); + } } catch (Exception e) {