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
No known key found for this signature in database
GPG key ID: 6618763EF09186FE
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);
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),
Guid.NewGuid().ToString(), TimeSpan.FromDays(40));

View file

@ -121,12 +121,7 @@ public class LightningAutomatedPayoutProcessor : BaseAutomatedPayoutProcessor<Li
var processorBlob = GetBlob(PayoutProcessorSettings);
var lightningSupportedPaymentMethod = (LightningPaymentMethodConfig)paymentMethodConfig;
if (lightningSupportedPaymentMethod.IsInternalNode &&
!(await Task.WhenAll((await _storeRepository.GetStoreUsers(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))
!await _storeRepository.InternalNodePayoutAuthorized(PayoutProcessorSettings.StoreId))
{
return false;
}

View file

@ -9,6 +9,7 @@ using BTCPayServer.Client;
using BTCPayServer.Data;
using BTCPayServer.Events;
using BTCPayServer.Migrations;
using Dapper;
using Microsoft.EntityFrameworkCore;
using NBitcoin;
using NBitcoin.DataEncoders;
@ -637,6 +638,23 @@ retry:
{
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

View file

@ -160,13 +160,6 @@ namespace BTCPayServer.Services
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)
{
using var scope = _serviceProvider.CreateScope();