mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-01-18 13:26:47 +01:00
Fix flaky test (#4330)
* Fix flaky test * Update BTCPayServer/PayoutProcessors/BaseAutomatedPayoutProcessor.cs Co-authored-by: d11n <mail@dennisreimann.de> Co-authored-by: d11n <mail@dennisreimann.de>
This commit is contained in:
parent
d959f5096b
commit
9404819dbe
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Import Project="../Build/Version.csproj" Condition="Exists('../Build/Version.csproj')" />
|
||||
<Import Project="../Build/Common.csproj" />
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
<PackageReference Include="Fido2" Version="2.0.2" />
|
||||
<PackageReference Include="Fido2.AspNet" Version="2.0.2" />
|
||||
<PackageReference Include="HtmlSanitizer" Version="5.0.372" />
|
||||
<PackageReference Include="LNURL" Version="0.0.24" />
|
||||
<PackageReference Include="LNURL" Version="0.0.26" />
|
||||
<PackageReference Include="MailKit" Version="3.3.0" />
|
||||
<PackageReference Include="McMaster.NETCore.Plugins.Mvc" Version="1.4.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
||||
|
@ -250,7 +250,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
|
||||
[HttpPost("~/api/v1/pull-payments/{pullPaymentId}/payouts")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> CreatePayout(string pullPaymentId, CreatePayoutRequest request)
|
||||
public async Task<IActionResult> CreatePayout(string pullPaymentId, CreatePayoutRequest request, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!PaymentMethodId.TryParse(request?.PaymentMethod, out var paymentMethodId))
|
||||
{
|
||||
@ -270,7 +270,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
if (pp is null)
|
||||
return PullPaymentNotFound();
|
||||
var ppBlob = pp.GetBlob();
|
||||
var destination = await payoutHandler.ParseAndValidateClaimDestination(paymentMethodId, request!.Destination, ppBlob);
|
||||
var destination = await payoutHandler.ParseAndValidateClaimDestination(paymentMethodId, request!.Destination, ppBlob, cancellationToken);
|
||||
if (destination.destination is null)
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.Destination), destination.error ?? "The destination is invalid for the payment specified");
|
||||
@ -332,7 +332,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
return PullPaymentNotFound();
|
||||
ppBlob = pp.GetBlob();
|
||||
}
|
||||
var destination = await payoutHandler.ParseAndValidateClaimDestination(paymentMethodId, request!.Destination, ppBlob);
|
||||
var destination = await payoutHandler.ParseAndValidateClaimDestination(paymentMethodId, request!.Destination, ppBlob, default);
|
||||
if (destination.destination is null)
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.Destination), destination.error ?? "The destination is invalid for the payment specified");
|
||||
|
@ -357,7 +357,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return GetFromActionResult<PayoutData>(
|
||||
await GetController<GreenfieldPullPaymentController>().CreatePayout(pullPaymentId, payoutRequest));
|
||||
await GetController<GreenfieldPullPaymentController>().CreatePayout(pullPaymentId, payoutRequest, cancellationToken));
|
||||
}
|
||||
|
||||
public override async Task CancelPayout(string storeId, string payoutId,
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Constants;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
@ -153,7 +154,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpPost("pull-payments/{pullPaymentId}/claim")]
|
||||
public async Task<IActionResult> ClaimPullPayment(string pullPaymentId, ViewPullPaymentModel vm)
|
||||
public async Task<IActionResult> ClaimPullPayment(string pullPaymentId, ViewPullPaymentModel vm, CancellationToken cancellationToken)
|
||||
{
|
||||
using var ctx = _dbContextFactory.CreateContext();
|
||||
var pp = await ctx.PullPayments.FindAsync(pullPaymentId);
|
||||
@ -172,7 +173,7 @@ namespace BTCPayServer.Controllers
|
||||
ModelState.AddModelError(nameof(vm.SelectedPaymentMethod), "Invalid destination with selected payment method");
|
||||
return await ViewPullPayment(pullPaymentId);
|
||||
}
|
||||
var destination = await payoutHandler.ParseAndValidateClaimDestination(paymentMethodId, vm.Destination, ppBlob);
|
||||
var destination = await payoutHandler.ParseAndValidateClaimDestination(paymentMethodId, vm.Destination, ppBlob, cancellationToken);
|
||||
if (destination.destination is null)
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.Destination), destination.error ?? "Invalid destination with selected payment method");
|
||||
|
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
@ -71,7 +72,7 @@ public class BitcoinLikePayoutHandler : IPayoutHandler
|
||||
await explorerClient.TrackAsync(TrackedSource.Create(bitcoinLikeClaimDestination.Address));
|
||||
}
|
||||
|
||||
public Task<(IClaimDestination destination, string error)> ParseClaimDestination(PaymentMethodId paymentMethodId, string destination)
|
||||
public Task<(IClaimDestination destination, string error)> ParseClaimDestination(PaymentMethodId paymentMethodId, string destination, CancellationToken cancellationToken)
|
||||
{
|
||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(paymentMethodId.CryptoCode);
|
||||
destination = destination.Trim();
|
||||
@ -287,7 +288,7 @@ public class BitcoinLikePayoutHandler : IPayoutHandler
|
||||
var blob = payout.GetBlob(_jsonSerializerSettings);
|
||||
if (payout.GetPaymentMethodId() != paymentMethodId)
|
||||
continue;
|
||||
var claim = await ParseClaimDestination(paymentMethodId, blob.Destination);
|
||||
var claim = await ParseClaimDestination(paymentMethodId, blob.Destination, default);
|
||||
switch (claim.destination)
|
||||
{
|
||||
case UriClaimDestination uriClaimDestination:
|
||||
|
@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using BTCPayServer.Client.Models;
|
||||
@ -15,11 +16,11 @@ public interface IPayoutHandler
|
||||
public bool CanHandle(PaymentMethodId paymentMethod);
|
||||
public Task TrackClaim(PaymentMethodId paymentMethodId, IClaimDestination claimDestination);
|
||||
//Allows payout handler to parse payout destinations on its own
|
||||
public Task<(IClaimDestination destination, string error)> ParseClaimDestination(PaymentMethodId paymentMethodId, string destination);
|
||||
public Task<(IClaimDestination destination, string error)> ParseClaimDestination(PaymentMethodId paymentMethodId, string destination, CancellationToken cancellationToken);
|
||||
public (bool valid, string? error) ValidateClaimDestination(IClaimDestination claimDestination, PullPaymentBlob? pullPaymentBlob);
|
||||
public async Task<(IClaimDestination? destination, string? error)> ParseAndValidateClaimDestination(PaymentMethodId paymentMethodId, string destination, PullPaymentBlob? pullPaymentBlob)
|
||||
public async Task<(IClaimDestination? destination, string? error)> ParseAndValidateClaimDestination(PaymentMethodId paymentMethodId, string destination, PullPaymentBlob? pullPaymentBlob, CancellationToken cancellationToken)
|
||||
{
|
||||
var res = await ParseClaimDestination(paymentMethodId, destination);
|
||||
var res = await ParseClaimDestination(paymentMethodId, destination, cancellationToken);
|
||||
if (res.destination is null)
|
||||
return res;
|
||||
var res2 = ValidateClaimDestination(res.destination, pullPaymentBlob);
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using BTCPayServer.Client.Models;
|
||||
@ -59,7 +60,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
: LightningLikePayoutHandlerClearnetNamedClient);
|
||||
}
|
||||
|
||||
public async Task<(IClaimDestination destination, string error)> ParseClaimDestination(PaymentMethodId paymentMethodId, string destination)
|
||||
public async Task<(IClaimDestination destination, string error)> ParseClaimDestination(PaymentMethodId paymentMethodId, string destination, CancellationToken cancellationToken)
|
||||
{
|
||||
destination = destination.Trim();
|
||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(paymentMethodId.CryptoCode);
|
||||
@ -72,7 +73,9 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
|
||||
if (lnurlTag is null)
|
||||
{
|
||||
var info = (LNURLPayRequest)(await LNURL.LNURL.FetchInformation(lnurl, CreateClient(lnurl)));
|
||||
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
using var t = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, cancellationToken);
|
||||
var info = (LNURLPayRequest)(await LNURL.LNURL.FetchInformation(lnurl, CreateClient(lnurl), t.Token));
|
||||
lnurlTag = info.Tag;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
}
|
||||
|
||||
[HttpPost("pull-payments/payouts/lightning/{cryptoCode}")]
|
||||
public async Task<IActionResult> ProcessLightningPayout(string cryptoCode, string[] payoutIds)
|
||||
public async Task<IActionResult> ProcessLightningPayout(string cryptoCode, string[] payoutIds, CancellationToken cancellationToken)
|
||||
{
|
||||
await SetStoreContext();
|
||||
|
||||
@ -164,27 +164,27 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
{
|
||||
ResultVM result;
|
||||
var blob = payoutData.GetBlob(_btcPayNetworkJsonSerializerSettings);
|
||||
var claim = await payoutHandler.ParseClaimDestination(pmi, blob.Destination);
|
||||
var claim = await payoutHandler.ParseClaimDestination(pmi, blob.Destination, cancellationToken);
|
||||
try
|
||||
{
|
||||
switch (claim.destination)
|
||||
{
|
||||
case LNURLPayClaimDestinaton lnurlPayClaimDestinaton:
|
||||
var lnurlResult = await GetInvoiceFromLNURL(payoutData, payoutHandler, blob,
|
||||
lnurlPayClaimDestinaton, network.NBitcoinNetwork);
|
||||
lnurlPayClaimDestinaton, network.NBitcoinNetwork, cancellationToken);
|
||||
if (lnurlResult.Item2 is not null)
|
||||
{
|
||||
result = lnurlResult.Item2;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await TrypayBolt(client, blob, payoutData, lnurlResult.Item1, pmi);
|
||||
result = await TrypayBolt(client, blob, payoutData, lnurlResult.Item1, pmi, cancellationToken);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BoltInvoiceClaimDestination item1:
|
||||
result = await TrypayBolt(client, blob, payoutData, item1.PaymentRequest, pmi);
|
||||
result = await TrypayBolt(client, blob, payoutData, item1.PaymentRequest, pmi, cancellationToken);
|
||||
|
||||
break;
|
||||
default:
|
||||
@ -216,7 +216,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
return View("LightningPayoutResult", results);
|
||||
}
|
||||
public static async Task<(BOLT11PaymentRequest, ResultVM)> GetInvoiceFromLNURL(PayoutData payoutData,
|
||||
LightningLikePayoutHandler handler,PayoutBlob blob, LNURLPayClaimDestinaton lnurlPayClaimDestinaton, Network network)
|
||||
LightningLikePayoutHandler handler,PayoutBlob blob, LNURLPayClaimDestinaton lnurlPayClaimDestinaton, Network network, CancellationToken cancellationToken)
|
||||
{
|
||||
var endpoint = lnurlPayClaimDestinaton.LNURL.IsValidEmail()
|
||||
? LNURL.LNURL.ExtractUriFromInternetIdentifier(lnurlPayClaimDestinaton.LNURL)
|
||||
@ -224,7 +224,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
var httpClient = handler.CreateClient(endpoint);
|
||||
var lnurlInfo =
|
||||
(LNURLPayRequest)await LNURL.LNURL.FetchInformation(endpoint, "payRequest",
|
||||
httpClient);
|
||||
httpClient, cancellationToken);
|
||||
var lm = new LightMoney(blob.CryptoAmount.Value, LightMoneyUnit.BTC);
|
||||
if (lm > lnurlInfo.MaxSendable || lm < lnurlInfo.MinSendable)
|
||||
{
|
||||
@ -241,7 +241,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
try
|
||||
{
|
||||
var lnurlPayRequestCallbackResponse =
|
||||
await lnurlInfo.SendRequest(lm, network, httpClient);
|
||||
await lnurlInfo.SendRequest(lm, network, httpClient, cancellationToken: cancellationToken);
|
||||
|
||||
return (lnurlPayRequestCallbackResponse.GetPaymentRequest(network), null);
|
||||
}
|
||||
@ -262,7 +262,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
public static readonly TimeSpan SendTimeout = TimeSpan.FromSeconds(20);
|
||||
public static async Task<ResultVM> TrypayBolt(
|
||||
ILightningClient lightningClient, PayoutBlob payoutBlob, PayoutData payoutData, BOLT11PaymentRequest bolt11PaymentRequest,
|
||||
PaymentMethodId pmi)
|
||||
PaymentMethodId pmi, CancellationToken cancellationToken)
|
||||
{
|
||||
var boltAmount = bolt11PaymentRequest.MinimumAmount.ToDecimal(LightMoneyUnit.BTC);
|
||||
if (boltAmount != payoutBlob.CryptoAmount)
|
||||
@ -283,14 +283,15 @@ namespace BTCPayServer.Data.Payouts.LightningLike
|
||||
{
|
||||
// TODO: Incorporate the changes from this PR here:
|
||||
// https://github.com/btcpayserver/BTCPayServer.Lightning/pull/106
|
||||
using var cts = new CancellationTokenSource(SendTimeout);
|
||||
using var timeout = new CancellationTokenSource(SendTimeout);
|
||||
using var c = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, cancellationToken);
|
||||
var result = await lightningClient.Pay(bolt11PaymentRequest.ToString(),
|
||||
new PayInvoiceParams()
|
||||
{
|
||||
Amount = bolt11PaymentRequest.MinimumAmount == LightMoney.Zero
|
||||
? new LightMoney((decimal)payoutBlob.CryptoAmount, LightMoneyUnit.BTC)
|
||||
: null
|
||||
}, cts.Token);
|
||||
}, c.Token);
|
||||
string message = null;
|
||||
if (result.Result == PayResult.Ok)
|
||||
{
|
||||
|
@ -383,7 +383,7 @@ namespace BTCPayServer.HostedServices
|
||||
var payoutHandler = _payoutHandlers.FindPayoutHandler(paymentMethod);
|
||||
if (payoutHandler is null)
|
||||
throw new InvalidOperationException($"No payout handler for {paymentMethod}");
|
||||
var dest = await payoutHandler.ParseClaimDestination(paymentMethod, payoutBlob.Destination);
|
||||
var dest = await payoutHandler.ParseClaimDestination(paymentMethod, payoutBlob.Destination, default);
|
||||
decimal minimumCryptoAmount =
|
||||
await payoutHandler.GetMinimumPayoutAmount(paymentMethod, dest.destination);
|
||||
if (cryptoAmount < minimumCryptoAmount)
|
||||
|
@ -423,7 +423,7 @@ WHERE cte.""Id""=p.""Id""
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var claim = await handler?.ParseClaimDestination(pmi, payoutData.GetBlob(_btcPayNetworkJsonSerializerSettings).Destination);
|
||||
var claim = await handler?.ParseClaimDestination(pmi, payoutData.GetBlob(_btcPayNetworkJsonSerializerSettings).Destination, default);
|
||||
payoutData.Destination = claim.destination?.Id;
|
||||
}
|
||||
await ctx.SaveChangesAsync();
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -55,7 +55,6 @@ public class LightningAutomatedPayoutProcessor : BaseAutomatedPayoutProcessor<Au
|
||||
protected override async Task Process(ISupportedPaymentMethod paymentMethod, List<PayoutData> payouts)
|
||||
{
|
||||
var lightningSupportedPaymentMethod = (LightningSupportedPaymentMethod)paymentMethod;
|
||||
|
||||
if (lightningSupportedPaymentMethod.IsInternalNode &&
|
||||
!(await Task.WhenAll((await _storeRepository.GetStoreUsers(_PayoutProcesserSettings.StoreId))
|
||||
.Where(user => user.Role == StoreRoles.Owner).Select(user => user.Id)
|
||||
@ -63,7 +62,6 @@ public class LightningAutomatedPayoutProcessor : BaseAutomatedPayoutProcessor<Au
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var client =
|
||||
lightningSupportedPaymentMethod.CreateLightningClient(_network, _options.Value,
|
||||
_lightningClientFactoryService);
|
||||
@ -71,7 +69,7 @@ public class LightningAutomatedPayoutProcessor : BaseAutomatedPayoutProcessor<Au
|
||||
foreach (var payoutData in payouts)
|
||||
{
|
||||
var blob = payoutData.GetBlob(_btcPayNetworkJsonSerializerSettings);
|
||||
var claim = await _payoutHandler.ParseClaimDestination(PaymentMethodId, blob.Destination);
|
||||
var claim = await _payoutHandler.ParseClaimDestination(PaymentMethodId, blob.Destination, CancellationToken);
|
||||
try
|
||||
{
|
||||
switch (claim.destination)
|
||||
@ -79,7 +77,7 @@ public class LightningAutomatedPayoutProcessor : BaseAutomatedPayoutProcessor<Au
|
||||
case LNURLPayClaimDestinaton lnurlPayClaimDestinaton:
|
||||
var lnurlResult = await UILightningLikePayoutController.GetInvoiceFromLNURL(payoutData,
|
||||
_payoutHandler, blob,
|
||||
lnurlPayClaimDestinaton, _network.NBitcoinNetwork);
|
||||
lnurlPayClaimDestinaton, _network.NBitcoinNetwork, CancellationToken);
|
||||
if (lnurlResult.Item2 is not null)
|
||||
{
|
||||
continue;
|
||||
@ -104,6 +102,6 @@ public class LightningAutomatedPayoutProcessor : BaseAutomatedPayoutProcessor<Au
|
||||
BOLT11PaymentRequest bolt11PaymentRequest)
|
||||
{
|
||||
return (await UILightningLikePayoutController.TrypayBolt(lightningClient, payoutBlob, payoutData, bolt11PaymentRequest,
|
||||
payoutData.GetPaymentMethodId())).Result == PayResult.Ok;
|
||||
payoutData.GetPaymentMethodId(), CancellationToken)).Result == PayResult.Ok;
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ namespace BTCPayServer.PayoutProcessors.OnChain
|
||||
}
|
||||
|
||||
var claimDestination =
|
||||
await _bitcoinLikePayoutHandler.ParseClaimDestination(paymentMethodId, blob.Destination);
|
||||
await _bitcoinLikePayoutHandler.ParseClaimDestination(paymentMethodId, blob.Destination, CancellationToken);
|
||||
if (!string.IsNullOrEmpty(claimDestination.error))
|
||||
{
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user