Optimize queries from payout processor at startup

This commit is contained in:
nicolas.dorier
2024-09-24 23:39:05 +09:00
parent c97c9d4ece
commit f00a71922f
4 changed files with 25 additions and 14 deletions

View File

@@ -4122,7 +4122,12 @@ namespace BTCPayServer.Tests
var resp = await tester.CustomerLightningD.Pay(inv.BOLT11); var resp = await tester.CustomerLightningD.Pay(inv.BOLT11);
Assert.Equal(PayResult.Ok, resp.Result); Assert.Equal(PayResult.Ok, resp.Result);
var store = tester.PayTester.GetService<StoreRepository>();
Assert.True(await store.InternalNodePayoutAuthorized(admin.StoreId));
Assert.False(await store.InternalNodePayoutAuthorized("blah"));
await admin.MakeAdmin(false);
Assert.False(await store.InternalNodePayoutAuthorized(admin.StoreId));
await admin.MakeAdmin(true);
var customerInvoice = await tester.CustomerLightningD.CreateInvoice(LightMoney.FromUnit(10, LightMoneyUnit.Satoshi), var customerInvoice = await tester.CustomerLightningD.CreateInvoice(LightMoney.FromUnit(10, LightMoneyUnit.Satoshi),
Guid.NewGuid().ToString(), TimeSpan.FromDays(40)); Guid.NewGuid().ToString(), TimeSpan.FromDays(40));

View File

@@ -121,12 +121,7 @@ public class LightningAutomatedPayoutProcessor : BaseAutomatedPayoutProcessor<Li
var processorBlob = GetBlob(PayoutProcessorSettings); var processorBlob = GetBlob(PayoutProcessorSettings);
var lightningSupportedPaymentMethod = (LightningPaymentMethodConfig)paymentMethodConfig; var lightningSupportedPaymentMethod = (LightningPaymentMethodConfig)paymentMethodConfig;
if (lightningSupportedPaymentMethod.IsInternalNode && if (lightningSupportedPaymentMethod.IsInternalNode &&
!(await Task.WhenAll((await _storeRepository.GetStoreUsers(PayoutProcessorSettings.StoreId)) !await _storeRepository.InternalNodePayoutAuthorized(PayoutProcessorSettings.StoreId))
.Where(user =>
user.StoreRole.ToPermissionSet(PayoutProcessorSettings.StoreId)
.Contains(Policies.CanModifyStoreSettings, PayoutProcessorSettings.StoreId))
.Select(user => user.Id)
.Select(s => _userService.IsAdminUser(s)))).Any(b => b))
{ {
return false; return false;
} }

View File

@@ -9,6 +9,7 @@ using BTCPayServer.Client;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Events; using BTCPayServer.Events;
using BTCPayServer.Migrations; using BTCPayServer.Migrations;
using Dapper;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NBitcoin; using NBitcoin;
using NBitcoin.DataEncoders; using NBitcoin.DataEncoders;
@@ -637,6 +638,23 @@ retry:
{ {
return ex.InnerException is Npgsql.PostgresException postgres && postgres.SqlState == "40P01"; return ex.InnerException is Npgsql.PostgresException postgres && postgres.SqlState == "40P01";
} }
public async Task<bool> InternalNodePayoutAuthorized(string storeId)
{
using var ctx = _ContextFactory.CreateContext();
return (await ctx.Database.GetDbConnection().ExecuteScalarAsync<bool?>("""
SELECT TRUE
FROM "UserStore" us
JOIN "StoreRoles" sr ON sr."Id" = us."Role"
JOIN "AspNetUserRoles" ur ON us."ApplicationUserId" = ur."UserId"
JOIN "AspNetRoles" r ON ur."RoleId" = r."Id"
WHERE
us."StoreDataId"=@storeId AND
r."NormalizedName"='SERVERADMIN' AND
'btcpay.store.canmodifystoresettings' = ANY(sr."Permissions")
LIMIT 1;
""", new { storeId })) is true;
}
} }
public record StoreRoleId public record StoreRoleId

View File

@@ -160,13 +160,6 @@ namespace BTCPayServer.Services
return res.Succeeded; return res.Succeeded;
} }
public async Task<bool> IsAdminUser(string userId)
{
using var scope = _serviceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
return Roles.HasServerAdmin(await userManager.GetRolesAsync(new ApplicationUser() { Id = userId }));
}
public async Task<bool> IsAdminUser(ApplicationUser user) public async Task<bool> IsAdminUser(ApplicationUser user)
{ {
using var scope = _serviceProvider.CreateScope(); using var scope = _serviceProvider.CreateScope();