Fix slow invoice creation

This commit is contained in:
nicolas.dorier
2018-04-09 16:25:31 +09:00
parent 8fdfb2c4f6
commit ac9b8d03d7
6 changed files with 35 additions and 35 deletions

View File

@@ -120,7 +120,6 @@ namespace BTCPayServer.Tests
.Build(); .Build();
_Host.Start(); _Host.Start();
InvoiceRepository = (InvoiceRepository)_Host.Services.GetService(typeof(InvoiceRepository)); InvoiceRepository = (InvoiceRepository)_Host.Services.GetService(typeof(InvoiceRepository));
((LightningLikePaymentHandler)_Host.Services.GetService(typeof(IPaymentMethodHandler<LightningSupportedPaymentMethod>))).SkipP2PTest = !InContainer;
} }
public string HostName public string HostName

View File

@@ -132,7 +132,8 @@ namespace BTCPayServer.Tests
{ {
Url = connectionType == LightningConnectionType.Charge ? parent.MerchantCharge.Client.Uri.AbsoluteUri : Url = connectionType == LightningConnectionType.Charge ? parent.MerchantCharge.Client.Uri.AbsoluteUri :
connectionType == LightningConnectionType.CLightning ? parent.MerchantLightningD.Address.AbsoluteUri connectionType == LightningConnectionType.CLightning ? parent.MerchantLightningD.Address.AbsoluteUri
: throw new NotSupportedException(connectionType.ToString()) : throw new NotSupportedException(connectionType.ToString()),
SkipPortTest = true
}, "save", "BTC"); }, "save", "BTC");
if (storeController.ModelState.ErrorCount != 0) if (storeController.ModelState.ErrorCount != 0)
Assert.False(true, storeController.ModelState.FirstOrDefault().Value.Errors[0].ErrorMessage); Assert.False(true, storeController.ModelState.FirstOrDefault().Value.Errors[0].ErrorMessage);

View File

@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
<Version>1.0.1.77</Version> <Version>1.0.1.78</Version>
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn> <NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc;
using BTCPayServer.Payments.Lightning; using BTCPayServer.Payments.Lightning;
using System.Net; using System.Net;
using BTCPayServer.Data; using BTCPayServer.Data;
using System.Threading;
namespace BTCPayServer.Controllers namespace BTCPayServer.Controllers
{ {
@@ -127,13 +128,20 @@ namespace BTCPayServer.Controllers
try try
{ {
var info = await handler.Test(paymentMethod, network); var info = await handler.Test(paymentMethod, network);
if (!vm.SkipPortTest)
{
using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(20)))
{
await handler.TestConnection(info, cts.Token);
}
}
vm.StatusMessage = $"Connection to the lightning node succeed ({info})"; vm.StatusMessage = $"Connection to the lightning node succeed ({info})";
} }
catch (Exception ex) catch (Exception ex)
{ {
vm.StatusMessage = $"Error: {ex.Message}"; vm.StatusMessage = $"Error: {ex.Message}";
return View(vm); return View(vm);
} }
return View(vm); return View(vm);
} }
} }

View File

@@ -23,5 +23,6 @@ namespace BTCPayServer.Models.StoreViewModels
} }
public string StatusMessage { get; set; } public string StatusMessage { get; set; }
public string InternalLightningNode { get; internal set; } public string InternalLightningNode { get; internal set; }
public bool SkipPortTest { get; set; }
} }
} }

View File

@@ -44,7 +44,7 @@ namespace BTCPayServer.Payments.Lightning
.Replace("{OrderId}", invoice.OrderId ?? "", StringComparison.OrdinalIgnoreCase); .Replace("{OrderId}", invoice.OrderId ?? "", StringComparison.OrdinalIgnoreCase);
lightningInvoice = await client.CreateInvoice(new LightMoney(due, LightMoneyUnit.BTC), description, expiry); lightningInvoice = await client.CreateInvoice(new LightMoney(due, LightMoneyUnit.BTC), description, expiry);
} }
catch(Exception ex) catch (Exception ex)
{ {
throw new PaymentMethodUnavailableException($"Impossible to create lightning invoice ({ex.Message})", ex); throw new PaymentMethodUnavailableException($"Impossible to create lightning invoice ({ex.Message})", ex);
} }
@@ -57,11 +57,6 @@ namespace BTCPayServer.Payments.Lightning
}; };
} }
/// <summary>
/// Used for testing
/// </summary>
public bool SkipP2PTest { get; set; }
public async Task<NodeInfo> Test(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network) public async Task<NodeInfo> Test(LightningSupportedPaymentMethod supportedPaymentMethod, BTCPayNetwork network)
{ {
if (!_Dashboard.IsFullySynched(network.CryptoCode, out var summary)) if (!_Dashboard.IsFullySynched(network.CryptoCode, out var summary))
@@ -94,38 +89,34 @@ namespace BTCPayServer.Payments.Lightning
throw new PaymentMethodUnavailableException($"The lightning is not synched ({blocksGap} blocks)"); throw new PaymentMethodUnavailableException($"The lightning is not synched ({blocksGap} blocks)");
} }
return new NodeInfo(info.NodeId, info.Address, info.P2PPort);
}
public async Task TestConnection(NodeInfo nodeInfo, CancellationToken cancellation)
{
try try
{ {
if (!SkipP2PTest) IPAddress address = null;
try
{ {
await TestConnection(info.Address, info.P2PPort, cts.Token); address = IPAddress.Parse(nodeInfo.Host);
}
catch
{
address = (await Dns.GetHostAddressesAsync(nodeInfo.Host)).FirstOrDefault();
}
if (address == null)
throw new PaymentMethodUnavailableException($"DNS did not resolved {nodeInfo.Host}");
using (var tcp = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
await WithTimeout(tcp.ConnectAsync(new IPEndPoint(address, nodeInfo.Port)), cancellation);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new PaymentMethodUnavailableException($"Error while connecting to the lightning node via {info.Address}:{info.P2PPort} ({ex.Message})"); throw new PaymentMethodUnavailableException($"Error while connecting to the lightning node via {nodeInfo.Host}:{nodeInfo.Port} ({ex.Message})");
}
return new NodeInfo(info.NodeId, info.Address, info.P2PPort);
}
private async Task TestConnection(string addressStr, int port, CancellationToken cancellation)
{
IPAddress address = null;
try
{
address = IPAddress.Parse(addressStr);
}
catch
{
address = (await Dns.GetHostAddressesAsync(addressStr)).FirstOrDefault();
}
if (address == null)
throw new PaymentMethodUnavailableException($"DNS did not resolved {addressStr}");
using (var tcp = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
await WithTimeout(tcp.ConnectAsync(new IPEndPoint(address, port)), cancellation);
} }
} }