update wabisabi

This commit is contained in:
Kukks
2023-03-09 12:04:11 +01:00
parent b9c0b5b697
commit d8318b7eb3
8 changed files with 63 additions and 29 deletions

View File

@@ -13,7 +13,7 @@
<PropertyGroup> <PropertyGroup>
<Product>Wabisabi Coinjoin</Product> <Product>Wabisabi Coinjoin</Product>
<Description>Allows you to integrate your btcpayserver store with coinjoins.</Description> <Description>Allows you to integrate your btcpayserver store with coinjoins.</Description>
<Version>1.0.21</Version> <Version>1.0.22</Version>
</PropertyGroup> </PropertyGroup>
<!-- Plugin development properties --> <!-- Plugin development properties -->

View File

@@ -599,7 +599,7 @@ public class BTCPayWallet : IWallet, IDestinationProvider
Logger.LogTrace($"unlocked utxos: {string.Join(',', unlocked)}"); Logger.LogTrace($"unlocked utxos: {string.Join(',', unlocked)}");
} }
public async Task<IEnumerable<IDestination>> GetNextDestinationsAsync(int count, bool preferTaproot, bool mixedOutputs) public async Task<IEnumerable<IDestination>> GetNextDestinationsAsync(int count, bool mixedOutputs)
{ {
if (!WabisabiStoreSettings.PlebMode && !string.IsNullOrEmpty(WabisabiStoreSettings.MixToOtherWallet) && mixedOutputs) if (!WabisabiStoreSettings.PlebMode && !string.IsNullOrEmpty(WabisabiStoreSettings.MixToOtherWallet) && mixedOutputs)
{ {
@@ -673,6 +673,11 @@ public async Task<IEnumerable<IDestination>> GetNextDestinationsAsync(int count,
} }
} }
public Task<ScriptType> GetScriptTypeAsync()
{
return Task.FromResult(DerivationScheme.GetDerivation(0).ScriptPubKey.GetScriptType());
}
private Action<(uint256 roundId, uint256 transactionId, int outputIndex)> PaymentSucceeded(string payoutId) private Action<(uint256 roundId, uint256 transactionId, int outputIndex)> PaymentSucceeded(string payoutId)
{ {

View File

@@ -56,7 +56,7 @@
@foreach (var cjData in Model) @foreach (var cjData in Model)
{ {
var cjInWeightedAverage = @CoinjoinAnalyzer.WeightedAverage.Invoke(@cjData.CoinsIn.Select(coin => new CoinjoinAnalyzer.AmountWithAnonymity(coin.AnonymitySet, new Money(coin.Amount, MoneyUnit.BTC)))); var cjInWeightedAverage = @CoinjoinAnalyzer.WeightedAverage.Invoke(@cjData.CoinsIn.Select(coin => new CoinjoinAnalyzer.AmountWithAnonymity(coin.AnonymitySet, new Money(coin.Amount, MoneyUnit.BTC))));
var cjOutWeightedAverage = @CoinjoinAnalyzer.WeightedAverage.Invoke(@cjData.CoinsOut.Select(coin => new CoinjoinAnalyzer.AmountWithAnonymity(coin.AnonymitySet, new Money(coin.Amount, MoneyUnit.BTC)))); var cjOutWeightedAverage = @CoinjoinAnalyzer.WeightedAverage.Invoke(@cjData.CoinsOut.Where(coin => coin.PayoutId is null).Select(coin => new CoinjoinAnalyzer.AmountWithAnonymity(coin.AnonymitySet, new Money(coin.Amount, MoneyUnit.BTC))));
<tr> <tr>
<td> <td>
<a class="text-break" data-bs-toggle="collapse" data-bs-target="#txcoins-@cjData.Round">@cjData.Round</a> <a class="text-break" data-bs-toggle="collapse" data-bs-target="#txcoins-@cjData.Round">@cjData.Round</a>

View File

@@ -19,6 +19,7 @@ using WalletWasabi.WabiSabi.Backend.PostRequests;
using WalletWasabi.WabiSabi.Client; using WalletWasabi.WabiSabi.Client;
using WalletWasabi.WabiSabi.Client.RoundStateAwaiters; using WalletWasabi.WabiSabi.Client.RoundStateAwaiters;
using WalletWasabi.WabiSabi.Client.StatusChangedEvents; using WalletWasabi.WabiSabi.Client.StatusChangedEvents;
using WalletWasabi.Wallets;
using WalletWasabi.WebClients.Wasabi; using WalletWasabi.WebClients.Wasabi;
using HttpClientFactory = WalletWasabi.WebClients.Wasabi.HttpClientFactory; using HttpClientFactory = WalletWasabi.WebClients.Wasabi.HttpClientFactory;
@@ -63,11 +64,18 @@ public class WabisabiCoordinatorClientInstanceManager:IHostedService
} }
} }
public async Task StopWallet(string name) public async Task StopWallet(IWallet wallet, string coordinator = null)
{
if (coordinator is not null && HostedServices.TryGetValue(coordinator, out var instance))
{
await instance.StopWallet(wallet);
}
else if (coordinator is null)
{ {
foreach (var servicesValue in HostedServices.Values) foreach (var servicesValue in HostedServices.Values)
{ {
await servicesValue.StopWallet(name); await servicesValue.StopWallet(wallet);
}
} }
} }
@@ -184,9 +192,9 @@ public class WabisabiCoordinatorClientInstance
} }
public async Task StopWallet(string walletName) public async Task StopWallet(IWallet wallet)
{ {
await CoinJoinManager.StopAsyncByName(walletName, CancellationToken.None); await CoinJoinManager.StopAsync(wallet, CancellationToken.None);
} }
private void OnStatusChanged(object sender, StatusChangedEventArgs e) private void OnStatusChanged(object sender, StatusChangedEventArgs e)

View File

@@ -66,7 +66,8 @@ public class WabisabiPlugin : BaseBTCPayServerPlugin
provider.GetRequiredService<IExplorerClientProvider>(), provider.GetRequiredService<IExplorerClientProvider>(),
provider.GetRequiredService<ILoggerFactory>(), provider.GetRequiredService<ILoggerFactory>(),
utxoLocker, utxoLocker,
provider.GetRequiredService<EventAggregator>() provider.GetRequiredService<EventAggregator>(),
provider.GetRequiredService<ILogger<WalletProvider>>()
)); ));
applicationBuilder.AddWabisabiCoordinator(); applicationBuilder.AddWabisabiCoordinator();
applicationBuilder.AddSingleton<IWalletProvider>(provider => provider.GetRequiredService<WalletProvider>()); applicationBuilder.AddSingleton<IWalletProvider>(provider => provider.GetRequiredService<WalletProvider>());
@@ -141,7 +142,7 @@ public class WabisabiPlugin : BaseBTCPayServerPlugin
{ {
var walletProvider = var walletProvider =
(WalletProvider)applicationBuilderApplicationServices.GetRequiredService<IWalletProvider>(); (WalletProvider)applicationBuilderApplicationServices.GetRequiredService<IWalletProvider>();
await walletProvider.ResetWabisabiStuckPayouts(); await walletProvider.ResetWabisabiStuckPayouts(null);
}); });
Logger.DotnetLogger = applicationBuilderApplicationServices.GetService<ILogger<WabisabiPlugin>>(); Logger.DotnetLogger = applicationBuilderApplicationServices.GetService<ILogger<WabisabiPlugin>>();

View File

@@ -62,11 +62,14 @@ namespace BTCPayServer.Plugins.Wabisabi
public async Task SetWabisabiForStore(string storeId, WabisabiStoreSettings wabisabiSettings, string termsCoord = null) public async Task SetWabisabiForStore(string storeId, WabisabiStoreSettings wabisabiSettings, string termsCoord = null)
{ {
foreach (var setting in wabisabiSettings.Settings) foreach (var setting in wabisabiSettings.Settings.Where(setting => !setting.Enabled))
{ {
if (setting.Enabled) continue; _walletProvider.LoadedWallets.TryGetValue(storeId, out var walletTask);
if(_coordinatorClientInstanceManager.HostedServices.TryGetValue(setting.Coordinator, out var coordinator)) if (walletTask != null)
_ = coordinator.StopWallet(storeId); {
var wallet = await walletTask;
await _coordinatorClientInstanceManager.StopWallet(wallet, setting.Coordinator);
}
} }
if (wabisabiSettings.Settings.All(settings => !settings.Enabled)) if (wabisabiSettings.Settings.All(settings => !settings.Enabled))

View File

@@ -39,6 +39,7 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
public IUTXOLocker UtxoLocker { get; set; } public IUTXOLocker UtxoLocker { get; set; }
private readonly ILoggerFactory _loggerFactory; private readonly ILoggerFactory _loggerFactory;
private readonly EventAggregator _eventAggregator; private readonly EventAggregator _eventAggregator;
private readonly ILogger<WalletProvider> _logger;
public WalletProvider( public WalletProvider(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
@@ -47,7 +48,8 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
IExplorerClientProvider explorerClientProvider, IExplorerClientProvider explorerClientProvider,
ILoggerFactory loggerFactory, ILoggerFactory loggerFactory,
IUTXOLocker utxoLocker, IUTXOLocker utxoLocker,
EventAggregator eventAggregator ) : base(TimeSpan.FromMinutes(5)) EventAggregator eventAggregator,
ILogger<WalletProvider> logger) : base(TimeSpan.FromMinutes(5))
{ {
UtxoLocker = utxoLocker; UtxoLocker = utxoLocker;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
@@ -56,7 +58,7 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
_explorerClientProvider = explorerClientProvider; _explorerClientProvider = explorerClientProvider;
_loggerFactory = loggerFactory; _loggerFactory = loggerFactory;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_logger = logger;
} }
public readonly ConcurrentDictionary<string, Task<IWallet?>> LoadedWallets = new(); public readonly ConcurrentDictionary<string, Task<IWallet?>> LoadedWallets = new();
@@ -65,9 +67,9 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
public class WalletUnloadEventArgs : EventArgs public class WalletUnloadEventArgs : EventArgs
{ {
public string Wallet { get; } public IWallet Wallet { get; }
public WalletUnloadEventArgs(string wallet) public WalletUnloadEventArgs(IWallet wallet)
{ {
Wallet = wallet; Wallet = wallet;
} }
@@ -76,7 +78,7 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
public event EventHandler<WalletUnloadEventArgs>? WalletUnloaded; public event EventHandler<WalletUnloadEventArgs>? WalletUnloaded;
public async Task<IWallet> GetWalletAsync(string name) public async Task<IWallet> GetWalletAsync(string name)
{ {
await initialLoad; await initialLoad.Task;
return await LoadedWallets.GetOrAddAsync(name, async s => return await LoadedWallets.GetOrAddAsync(name, async s =>
{ {
@@ -118,7 +120,7 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
} }
private Task initialLoad = null; private TaskCompletionSource initialLoad = new();
private IEventAggregatorSubscription _subscription; private IEventAggregatorSubscription _subscription;
private IEventAggregatorSubscription _subscription2; private IEventAggregatorSubscription _subscription2;
@@ -131,7 +133,7 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
return Array.Empty<IWallet>(); return Array.Empty<IWallet>();
} }
await initialLoad; await initialLoad.Task;
return (await Task.WhenAll(_cachedSettings return (await Task.WhenAll(_cachedSettings
.Select(pair => GetWalletAsync(pair.Key)))) .Select(pair => GetWalletAsync(pair.Key))))
.Where(wallet => wallet is not null); .Where(wallet => wallet is not null);
@@ -139,22 +141,32 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
public async Task ResetWabisabiStuckPayouts() public async Task ResetWabisabiStuckPayouts(string[] storeIds)
{ {
var wallets = await GetWalletsAsync();
await initialLoad.Task;
storeIds??= _cachedSettings?.Keys.ToArray() ?? Array.Empty<string>();
if (!storeIds.Any())
{
return;
}
var pullPaymentHostedService = _serviceProvider.GetRequiredService<PullPaymentHostedService>(); var pullPaymentHostedService = _serviceProvider.GetRequiredService<PullPaymentHostedService>();
var payouts = await pullPaymentHostedService.GetPayouts(new PullPaymentHostedService.PayoutQuery() var payouts = await pullPaymentHostedService.GetPayouts(new PullPaymentHostedService.PayoutQuery()
{ {
States = new PayoutState[] States = new[]
{ {
PayoutState.InProgress PayoutState.InProgress
}, },
PaymentMethods = new[] {"BTC"}, PaymentMethods = new[] {"BTC"},
Stores = wallets.Select(wallet => ((BTCPayWallet) wallet).StoreId).ToArray() Stores = storeIds
}); });
var inProgressPayouts = payouts var inProgressPayouts = payouts
.Where(data => data.GetProofBlobJson()?.Value<string>("proofType") == "Wabisabi").ToArray(); .Where(data => data.GetProofBlobJson()?.Value<string>("proofType") == "Wabisabi").ToArray();
if(!inProgressPayouts.Any())
return;
_logger.LogInformation("Moving {count} stuck coinjoin payouts to AwaitingPayment", inProgressPayouts.Length);
foreach (PayoutData payout in inProgressPayouts) foreach (PayoutData payout in inProgressPayouts)
{ {
try try
@@ -217,8 +229,12 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
private async Task UnloadWallet(string name) private async Task UnloadWallet(string name)
{ {
LoadedWallets.TryRemove(name, out _); LoadedWallets.TryRemove(name, out var walletTask);
WalletUnloaded?.Invoke(this, new WalletUnloadEventArgs(name)); if (walletTask != null)
{
var wallet = await walletTask;
WalletUnloaded?.Invoke(this, new WalletUnloadEventArgs(wallet));
}
} }
public async Task SettingsUpdated(string storeId, WabisabiStoreSettings wabisabiSettings) public async Task SettingsUpdated(string storeId, WabisabiStoreSettings wabisabiSettings)
@@ -269,10 +285,11 @@ public class WalletProvider : PeriodicRunner,IWalletProvider
public override Task StartAsync(CancellationToken cancellationToken) public override Task StartAsync(CancellationToken cancellationToken)
{ {
initialLoad = Task.Run(async () => Task.Run(async () =>
{ {
_cachedSettings = _cachedSettings =
await _storeRepository.GetSettingsAsync<WabisabiStoreSettings>(nameof(WabisabiStoreSettings)); await _storeRepository.GetSettingsAsync<WabisabiStoreSettings>(nameof(WabisabiStoreSettings));
initialLoad.SetResult();
}, cancellationToken); }, cancellationToken);
_subscription = _eventAggregator.SubscribeAsync<WalletChangedEvent>(@event => _subscription = _eventAggregator.SubscribeAsync<WalletChangedEvent>(@event =>
Check(@event.WalletId.StoreId, cancellationToken)); Check(@event.WalletId.StoreId, cancellationToken));