mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-13 11:35:51 +01:00
Lightning: Better handling for non-public nodes (#4263)
Fixes #4246. `LightningLikePaymentHandler.GetNodeInfo` needed the `throws` argument to handle the cases as previously, otherwise the catch case in `ShowLightningNodeInfo` never occured. State with this PR: A node can be available, but not have any public addresses. The latter will now be reported when testing the connection and on the public node info page.
This commit is contained in:
parent
167c5297fa
commit
562f88555c
4 changed files with 39 additions and 35 deletions
|
@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||
|
||||
namespace BTCPayServer.Controllers
|
||||
{
|
||||
|
||||
[Route("embed/{storeId}/{cryptoCode}/ln")]
|
||||
[AllowAnonymous]
|
||||
public class UIPublicLightningNodeInfoController : Controller
|
||||
|
@ -43,11 +42,11 @@ namespace BTCPayServer.Controllers
|
|||
var paymentMethodDetails = GetExistingLightningSupportedPaymentMethod(cryptoCode, store);
|
||||
var network = _BtcPayNetworkProvider.GetNetwork<BTCPayNetwork>(cryptoCode);
|
||||
var nodeInfo =
|
||||
await _LightningLikePaymentHandler.GetNodeInfo(paymentMethodDetails, network, new InvoiceLogs());
|
||||
await _LightningLikePaymentHandler.GetNodeInfo(paymentMethodDetails, network, new InvoiceLogs(), throws: true);
|
||||
|
||||
return View(new ShowLightningNodeInfoViewModel
|
||||
{
|
||||
Available = nodeInfo.Any(),
|
||||
Available = true,
|
||||
NodeInfo = nodeInfo.Select(n => new ShowLightningNodeInfoViewModel.NodeData(n)).ToArray(),
|
||||
CryptoCode = cryptoCode,
|
||||
CryptoImage = GetImage(paymentMethodDetails.PaymentId, network),
|
||||
|
|
|
@ -194,12 +194,15 @@ namespace BTCPayServer.Controllers
|
|||
try
|
||||
{
|
||||
var info = await handler.GetNodeInfo(paymentMethod, network, new InvoiceLogs(), Request.IsOnion(), true);
|
||||
if (!vm.SkipPortTest)
|
||||
var hasPublicAddress = info.Any();
|
||||
if (!vm.SkipPortTest && hasPublicAddress)
|
||||
{
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(20));
|
||||
await handler.TestConnection(info.First(), cts.Token);
|
||||
}
|
||||
TempData[WellKnownTempData.SuccessMessage] = $"Connection to the Lightning node successful. Your node address: {info.First()}";
|
||||
TempData[WellKnownTempData.SuccessMessage] = "Connection to the Lightning node successful" + (hasPublicAddress
|
||||
? $". Your node address: {info.First()}"
|
||||
: ", but no public address has been configured");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -225,7 +228,7 @@ namespace BTCPayServer.Controllers
|
|||
var lightning = GetExistingLightningSupportedPaymentMethod(cryptoCode, store);
|
||||
if (lightning == null)
|
||||
{
|
||||
TempData[WellKnownTempData.ErrorMessage] = $"You need to connect to a Lightning node before adjusting its settings.";
|
||||
TempData[WellKnownTempData.ErrorMessage] = "You need to connect to a Lightning node before adjusting its settings.";
|
||||
|
||||
return RedirectToAction(nameof(SetupLightningNode), new { storeId, cryptoCode });
|
||||
}
|
||||
|
|
|
@ -147,16 +147,11 @@ namespace BTCPayServer.Payments.Lightning
|
|||
(!string.IsNullOrEmpty(ex.InnerException?.Message) ? $" ({ex.InnerException.Message})" : ""));
|
||||
}
|
||||
|
||||
// Node info might be empty if there are no public URIs to announce. The UI also supports this.
|
||||
var nodeInfo = preferOnion != null && info.NodeInfoList.Any(i => i.IsTor == preferOnion)
|
||||
? info.NodeInfoList.Where(i => i.IsTor == preferOnion.Value).ToArray()
|
||||
: info.NodeInfoList.Select(i => i).ToArray();
|
||||
|
||||
// Maybe the user does not have an easily accessible ln node. Node info should be optional. The UI also supports this.
|
||||
// if (!nodeInfo.Any())
|
||||
// {
|
||||
// throw new PaymentMethodUnavailableException("No lightning node public address has been configured");
|
||||
// }
|
||||
|
||||
var blocksGap = summary.Status.ChainHeight - info.BlockHeight;
|
||||
if (blocksGap > 10)
|
||||
{
|
||||
|
|
|
@ -28,34 +28,41 @@
|
|||
</h4>
|
||||
@if (Model.Available)
|
||||
{
|
||||
@if (Model.NodeInfo.Length > 1)
|
||||
@if (Model.NodeInfo.Any())
|
||||
{
|
||||
<ul class="nav nav-pills justify-content-center mt-4" id="nodeInfo-tab" role="tablist">
|
||||
@if (Model.NodeInfo.Length > 1)
|
||||
{
|
||||
<ul class="nav nav-pills justify-content-center mt-4" id="nodeInfo-tab" role="tablist">
|
||||
@for (var i = 0; i < Model.NodeInfo.Length; i++)
|
||||
{
|
||||
var nodeInfo = Model.NodeInfo[i];
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link w-100px @(i == 0 ? "active" : "")" id="nodeInfo-tab-@i" data-bs-toggle="pill" data-bs-target="#nodeInfo-@i" type="button" role="tab" aria-controls="nodeInfo-@i" aria-selected="true">@(nodeInfo.IsTor ? "Tor" : "Clearnet")</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
<div class="tab-content" id="nodeInfo-tabContent">
|
||||
@for (var i = 0; i < Model.NodeInfo.Length; i++)
|
||||
{
|
||||
var nodeInfo = Model.NodeInfo[i];
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link w-100px @(i == 0 ? "active" : "")" id="nodeInfo-tab-@i" data-bs-toggle="pill" data-bs-target="#nodeInfo-@i" type="button" role="tab" aria-controls="nodeInfo-@i" aria-selected="true">@(nodeInfo.IsTor ? "Tor" : "Clearnet")</button>
|
||||
</li>
|
||||
var nodeInfo = Model.NodeInfo[i].ToString();
|
||||
<div class="tab-pane fade @(i == 0 ? "show active" : "")" id="nodeInfo-@i" role="tabpanel" aria-labelledby="nodeInfo-tab-@i">
|
||||
<div class="qr-container my-4 w-100">
|
||||
<img alt="@Model.CryptoCode" class="qr-icon" src="@Model.CryptoImage"/>
|
||||
<vc:qr-code data="@nodeInfo"/>
|
||||
</div>
|
||||
<div class="input-group" data-clipboard="@nodeInfo">
|
||||
<input type="text" class="form-control" style="cursor:copy" readonly="readonly" value="@nodeInfo" id="nodeInfo-addr-@i"/>
|
||||
<button type="button" class="btn btn-outline-secondary" data-clipboard-confirm>Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="text-center mt-4">No public address available.</p>
|
||||
}
|
||||
<div class="tab-content" id="nodeInfo-tabContent">
|
||||
@for (var i = 0; i < Model.NodeInfo.Length; i++)
|
||||
{
|
||||
var nodeInfo = Model.NodeInfo[i].ToString();
|
||||
<div class="tab-pane fade @(i == 0 ? "show active" : "")" id="nodeInfo-@i" role="tabpanel" aria-labelledby="nodeInfo-tab-@i">
|
||||
<div class="qr-container my-4 w-100">
|
||||
<img alt="@Model.CryptoCode" class="qr-icon" src="@Model.CryptoImage"/>
|
||||
<vc:qr-code data="@nodeInfo"/>
|
||||
</div>
|
||||
<div class="input-group" data-clipboard="@nodeInfo">
|
||||
<input type="text" class="form-control" style="cursor:copy" readonly="readonly" value="@nodeInfo" id="nodeInfo-addr-@i"/>
|
||||
<button type="button" class="btn btn-outline-secondary" data-clipboard-confirm>Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue