Simplify LND implementation

This commit is contained in:
nicolas.dorier
2018-07-08 18:55:48 +09:00
parent 0879895678
commit b9e8408db5
7 changed files with 51 additions and 94 deletions

View File

@@ -15,12 +15,12 @@ namespace BTCPayServer.Tests.Lnd
this._Parent = serverTester;
var url = serverTester.GetEnvironment(environmentName, defaultValue);
Swagger = LndSwaggerClientCustomHttp.Create(new Uri(url), network);
Swagger = new LndSwaggerClient(new LndRestSettings(new Uri(url)));
Client = new LndInvoiceClient(Swagger);
P2PHost = _Parent.GetEnvironment(environmentName + "_HOST", defaultHost);
}
public LndSwaggerClientCustomHttp Swagger { get; set; }
public LndSwaggerClient Swagger { get; set; }
public LndInvoiceClient Client { get; set; }
public string P2PHost { get; }
}

View File

@@ -25,16 +25,16 @@ namespace BTCPayServer.Tests.Lnd
this.output = output;
initializeEnvironment();
MerchantLnd = LndSwaggerClientCustomHttp.Create(new Uri("http://127.0.0.1:53280"), Network.RegTest);
MerchantLnd = new LndSwaggerClient(new LndRestSettings(new Uri("http://127.0.0.1:53280")));
InvoiceClient = new LndInvoiceClient(MerchantLnd);
CustomerLnd = LndSwaggerClientCustomHttp.Create(new Uri("http://127.0.0.1:53281"), Network.RegTest);
CustomerLnd = new LndSwaggerClient(new LndRestSettings(new Uri("http://127.0.0.1:53281")));
}
private LndSwaggerClientCustomHttp MerchantLnd { get; set; }
private LndSwaggerClient MerchantLnd { get; set; }
private LndInvoiceClient InvoiceClient { get; set; }
private LndSwaggerClientCustomHttp CustomerLnd { get; set; }
private LndSwaggerClient CustomerLnd { get; set; }
[Fact]
public async Task GetInfo()

View File

@@ -521,7 +521,7 @@ namespace BTCPayServer.Tests
Assert.Equal(lndUri, conn.ToString());
Assert.Equal(LightningConnectionType.LndREST, conn.ConnectionType);
Assert.Equal(macaroon, Encoders.Hex.EncodeData(conn.Macaroon));
Assert.Equal(tls, Encoders.Hex.EncodeData(conn.Tls));
Assert.Equal(tls, Encoders.Hex.EncodeData(conn.Tls.RawData));
}
[Fact]

View File

@@ -30,8 +30,11 @@ namespace BTCPayServer.Payments.Lightning
}
else if (connString.ConnectionType == LightningConnectionType.LndREST)
{
var swagger = LndSwaggerClientCustomHttp.Create(connString.BaseUri, network, connString.Tls, connString.Macaroon);
return new LndInvoiceClient(swagger);
return new LndInvoiceClient(new LndSwaggerClient(new LndRestSettings(connString.BaseUri)
{
Macaroon = connString.Macaroon,
TLS = connString.Tls
}));
}
else
throw new NotSupportedException($"Unsupported connection string for lightning server ({connString.ConnectionType})");

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@@ -197,11 +198,11 @@ namespace BTCPayServer.Payments.Lightning
{
var tls = Take(keyValues, "tls");
if (tls != null)
result.Tls = Encoder.DecodeData(tls);
result.Tls = new X509Certificate2(Encoder.DecodeData(tls));
}
catch
{
error = $"The key 'tls' format should be in hex";
error = $"The key 'tls' should be the X509 certificate in hex";
return false;
}
}
@@ -301,7 +302,7 @@ namespace BTCPayServer.Payments.Lightning
private set;
}
public byte[] Macaroon { get; set; }
public byte[] Tls { get; set; }
public X509Certificate2 Tls { get; set; }
public Uri ToUri(bool withCredentials)
{
@@ -350,7 +351,7 @@ namespace BTCPayServer.Payments.Lightning
}
if (Tls != null)
{
builder.Append($";tls={Encoder.EncodeData(Tls)}");
builder.Append($";tls={Encoder.EncodeData(Tls.RawData)}");
}
break;
default:

View File

@@ -19,9 +19,11 @@ namespace BTCPayServer.Payments.Lightning.Lnd
{
public LndSwaggerClient _rpcClient;
public LndInvoiceClient(LndSwaggerClient rpcClient)
public LndInvoiceClient(LndSwaggerClient swaggerClient)
{
_rpcClient = rpcClient;
if (swaggerClient == null)
throw new ArgumentNullException(nameof(swaggerClient));
_rpcClient = swaggerClient;
}
public async Task<LightningInvoice> CreateInvoice(LightMoney amount, string description, TimeSpan expiry,

View File

@@ -16,102 +16,53 @@ using Newtonsoft.Json.Linq;
namespace BTCPayServer.Payments.Lightning.Lnd
{
public class LndSwaggerClientCustomHttp : LndSwaggerClient, IDisposable
public class LndRestSettings
{
protected LndSwaggerClientCustomHttp(string baseUrl, HttpClient httpClient)
: base(baseUrl, httpClient)
public LndRestSettings()
{
_HttpClient = httpClient;
}
public LndRestSettings(Uri uri)
{
Uri = uri;
}
public Uri Uri { get; set; }
public X509Certificate2 TLS { get; set; }
public byte[] Macaroon { get; set; }
}
private HttpClient _HttpClient;
public void Dispose()
public partial class LndSwaggerClient
{
_HttpClient.Dispose();
}
//
public static LndSwaggerClientCustomHttp Create(Uri uri, Network network, byte[] tlsCertificate = null, byte[] grpcMacaroon = null)
public LndSwaggerClient(LndRestSettings settings)
: this(settings.Uri.AbsoluteUri.TrimEnd('/'), CreateHttpClient(settings))
{
var factory = new HttpClientFactoryForLnd(tlsCertificate, grpcMacaroon);
var httpClient = factory.Generate();
var swagger = new LndSwaggerClientCustomHttp(uri.ToString().TrimEnd('/'), httpClient);
swagger.HttpClientFactory = factory;
return swagger;
_Settings = settings;
}
}
internal class HttpClientFactoryForLnd
{
public HttpClientFactoryForLnd(byte[] tlsCertificate = null, byte[] grpcMacaroon = null)
{
TlsCertificate = tlsCertificate;
GrpcMacaroon = grpcMacaroon;
}
public byte[] TlsCertificate { get; set; }
public byte[] GrpcMacaroon { get; set; }
public HttpClient Generate()
{
var httpClient = new HttpClient(GetCertificate(TlsCertificate));
if (GrpcMacaroon != null)
{
var macaroonHex = BitConverter.ToString(GrpcMacaroon).Replace("-", "", StringComparison.InvariantCulture);
httpClient.DefaultRequestHeaders.Add("Grpc-Metadata-macaroon", macaroonHex);
}
return httpClient;
}
private static HttpClientHandler GetCertificate(byte[] certFile)
LndRestSettings _Settings;
private static HttpClient CreateHttpClient(LndRestSettings settings)
{
var handler = new HttpClientHandler
{
SslProtocols = SslProtocols.Tls12
};
if (certFile == null)
var expectedCertificate = settings.TLS;
if (expectedCertificate != null)
{
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
return handler;
}
// if certificate is not null, try with custom accepting logic
X509Certificate2 clientCertificate = null;
if (certFile != null)
clientCertificate = new X509Certificate2(certFile);
handler.ServerCertificateCustomValidationCallback = (request, cert, chain, errors) =>
{
const SslPolicyErrors unforgivableErrors =
SslPolicyErrors.RemoteCertificateNotAvailable |
SslPolicyErrors.RemoteCertificateNameMismatch;
if ((errors & unforgivableErrors) != 0)
{
return false;
}
if (clientCertificate == null)
return true;
X509Certificate2 remoteRoot = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
var res = clientCertificate.RawData.SequenceEqual(remoteRoot.RawData);
return res;
return expectedCertificate.RawData.SequenceEqual(remoteRoot.RawData);
};
return handler;
}
}
public partial class LndSwaggerClient
var httpClient = new HttpClient(handler);
if (settings.Macaroon != null)
{
internal HttpClientFactoryForLnd HttpClientFactory { get; set; }
var macaroonHex = BitConverter.ToString(settings.Macaroon).Replace("-", "", StringComparison.InvariantCulture);
httpClient.DefaultRequestHeaders.Add("Grpc-Metadata-macaroon", macaroonHex);
}
return httpClient;
}
public TaskCompletionSource<LnrpcInvoice> InvoiceResponse = new TaskCompletionSource<LnrpcInvoice>();
public TaskCompletionSource<LndSwaggerClient> SubscribeLost = new TaskCompletionSource<LndSwaggerClient>();
@@ -122,7 +73,7 @@ namespace BTCPayServer.Payments.Lightning.Lnd
var urlBuilder = new StringBuilder();
urlBuilder.Append(BaseUrl).Append("/v1/invoices/subscribe");
using (var client = HttpClientFactory.Generate())
using (var client = CreateHttpClient(_Settings))
{
client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);