Add OverridePlebStop to CoinJoinManager
MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinManager.cs
WalletWasabi/WabiSabi/Client/CoinJoinManager.cs
@@ -23,7 +23,7 @@ namespace WalletWasabi.WabiSabi.Client;
public class CoinJoinManager : BackgroundService
{
private record CoinJoinCommand(Wallet Wallet);
- private record StartCoinJoinCommand(Wallet Wallet, bool RestartAutomatically) : CoinJoinCommand(Wallet);
+ private record StartCoinJoinCommand(Wallet Wallet, bool RestartAutomatically, bool OverridePlebStop) : CoinJoinCommand(Wallet);
private record StopCoinJoinCommand(Wallet Wallet) : CoinJoinCommand(Wallet);
public CoinJoinManager(WalletManager walletManager, RoundStateUpdater roundStatusUpdater, IWasabiHttpClientFactory backendHttpClientFactory, ServiceConfiguration serviceConfiguration)
@@ -49,14 +49,15 @@ public class CoinJoinManager : BackgroundService
#region Public API (Start | Stop | StartAutomatically)
- public async Task StartAsync(Wallet wallet, CancellationToken cancellationToken)
- {
- await CommandChannel.Writer.WriteAsync(new StartCoinJoinCommand(wallet, false), cancellationToken).ConfigureAwait(false);
- }
+ public Task StartAsync(Wallet wallet, bool overridePlebStop, CancellationToken cancellationToken)
+ => StartAsync(wallet, restartAutomatically: false, overridePlebStop, cancellationToken);
+
+ public Task StartAutomaticallyAsync(Wallet wallet, bool overridePlebStop, CancellationToken cancellationToken)
+ => StartAsync(wallet, restartAutomatically: true, overridePlebStop, cancellationToken);
- public async Task StartAutomaticallyAsync(Wallet wallet, CancellationToken cancellationToken)
+ private async Task StartAsync(Wallet wallet, bool restartAutomatically, bool overridePlebStop, CancellationToken cancellationToken)
{
- await CommandChannel.Writer.WriteAsync(new StartCoinJoinCommand(wallet, true), cancellationToken).ConfigureAwait(false);
+ await CommandChannel.Writer.WriteAsync(new StartCoinJoinCommand(wallet, restartAutomatically, overridePlebStop), cancellationToken).ConfigureAwait(false);
}
public async Task StopAsync(Wallet wallet, CancellationToken cancellationToken)
@@ -144,12 +145,11 @@ public class CoinJoinManager : BackgroundService
return;
}
- // Only take PlebStop into account when AutoCoinJoin.
- if (startCommand.RestartAutomatically && walletToStart.NonPrivateCoins.TotalAmount() <= walletToStart.KeyManager.PlebStopThreshold)
+ if (walletToStart.IsUnderPlebStop && !startCommand.OverridePlebStop)
{
Logger.LogDebug($"PlebStop preventing coinjoin for wallet '{walletToStart.WalletName}'.");
NotifyCoinJoinStartError(walletToStart, CoinjoinError.NotEnoughUnprivateBalance);
- ScheduleRestartAutomatically(walletToStart);
+ ScheduleRestartAutomatically(walletToStart, startCommand.OverridePlebStop);
return;
}
@@ -160,12 +160,12 @@ public class CoinJoinManager : BackgroundService
NotifyCoinJoinStartError(walletToStart, CoinjoinError.NoCoinsToMix);
if (startCommand.RestartAutomatically)
{
- ScheduleRestartAutomatically(walletToStart);
+ ScheduleRestartAutomatically(walletToStart, startCommand.OverridePlebStop);
}
return;
}
- var coinJoinTracker = coinJoinTrackerFactory.CreateAndStart(walletToStart, coinCandidates, startCommand.RestartAutomatically);
+ var coinJoinTracker = coinJoinTrackerFactory.CreateAndStart(walletToStart, coinCandidates, startCommand.RestartAutomatically, startCommand.OverridePlebStop);
coinJoinTracker.WalletCoinJoinProgressChanged += CoinJoinTracker_WalletCoinJoinProgressChanged;
trackedCoinJoins.AddOrUpdate(walletToStart.WalletName, _ => coinJoinTracker, (_, cjt) => cjt);
@@ -183,7 +183,7 @@ public class CoinJoinManager : BackgroundService
}
}
- void ScheduleRestartAutomatically(Wallet walletToStart)
+ void ScheduleRestartAutomatically(Wallet walletToStart, bool overridePlebStop)
{
if (trackedAutoStarts.ContainsKey(walletToStart))
{
@@ -196,7 +196,14 @@ public class CoinJoinManager : BackgroundService
await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken).ConfigureAwait(false);
if (trackedAutoStarts.TryRemove(walletToStart, out _))
{
- await StartAutomaticallyAsync(walletToStart, stoppingToken).ConfigureAwait(false);
+ if (overridePlebStop && !walletToStart.IsUnderPlebStop)
+ {
+ // Turn off overriding if we went above the threshold meanwhile.
+ overridePlebStop = false;
+ Logger.LogDebug($"Do not override PlebStop for wallet '{walletToStart.WalletName}' anymore we are above the threshold.");
+ }
+
+ await StartAutomaticallyAsync(walletToStart, overridePlebStop, stoppingToken).ConfigureAwait(false);
}
else
{
@@ -314,7 +321,7 @@ public class CoinJoinManager : BackgroundService
{
Logger.LogInfo($"{logPrefix} restart automatically.");
- await StartAutomaticallyAsync(finishedCoinJoin.Wallet, cancellationToken).ConfigureAwait(false);
+ await StartAutomaticallyAsync(finishedCoinJoin.Wallet, finishedCoinJoin.OverridePlebStop, cancellationToken).ConfigureAwait(false);
}
}

MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinTracker.cs
WalletWasabi/WabiSabi/Client/CoinJoinTracker.cs
@@ -16,6 +16,7 @@ public class CoinJoinTracker : IDisposable
CoinJoinClient coinJoinClient,
IEnumerable<SmartCoin> coinCandidates,
bool restartAutomatically,
+ bool overridePlebStop,
CancellationToken cancellationToken)
{
Wallet = wallet;
@@ -24,6 +25,7 @@ public class CoinJoinTracker : IDisposable
CoinCandidates = coinCandidates;
RestartAutomatically = restartAutomatically;
+ OverridePlebStop = overridePlebStop;
CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
CoinJoinTask = coinJoinClient.StartCoinJoinAsync(coinCandidates, CancellationTokenSource.Token);
}
@@ -37,6 +39,7 @@ public class CoinJoinTracker : IDisposable
public Task<CoinJoinResult> CoinJoinTask { get; }
public IEnumerable<SmartCoin> CoinCandidates { get; }
public bool RestartAutomatically { get; }
+ public bool OverridePlebStop { get; }
public bool IsCompleted => CoinJoinTask.IsCompleted;
public bool InCriticalCoinJoinState => CoinJoinClient.InCriticalCoinJoinState;

MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinTrackerFactory.cs
WalletWasabi/WabiSabi/Client/CoinJoinTrackerFactory.cs
@@ -23,7 +23,7 @@ public class CoinJoinTrackerFactory
private RoundStateUpdater RoundStatusUpdater { get; }
private CancellationToken CancellationToken { get; }
- public CoinJoinTracker CreateAndStart(Wallet wallet, IEnumerable<SmartCoin> coinCandidates, bool restartAutomatically)
+ public CoinJoinTracker CreateAndStart(Wallet wallet, IEnumerable<SmartCoin> coinCandidates, bool restartAutomatically, bool overridePlebStop)
{
var coinJoinClient = new CoinJoinClient(
HttpClientFactory,
@@ -34,6 +34,6 @@ public class CoinJoinTrackerFactory
feeRateMedianTimeFrame: TimeSpan.FromHours(wallet.KeyManager.FeeRateMedianTimeFrameHours),
doNotRegisterInLastMinuteTimeLimit: TimeSpan.FromMinutes(1));
- return new CoinJoinTracker(wallet, coinJoinClient, coinCandidates, restartAutomatically, CancellationToken);
+ return new CoinJoinTracker(wallet, coinJoinClient, coinCandidates, restartAutomatically, overridePlebStop, CancellationToken);
}
}

MODIFY
WalletWasabi/Wallets/Wallet.cs
WalletWasabi/Wallets/Wallet.cs
@@ -96,6 +96,8 @@ public class Wallet : BackgroundService
public Kitchen Kitchen { get; } = new();
public ICoinsView NonPrivateCoins => new CoinsView(Coins.Where(c => c.HdPubKey.AnonymitySet < KeyManager.MinAnonScoreTarget));
+ public bool IsUnderPlebStop => NonPrivateCoins.TotalAmount() <= KeyManager.PlebStopThreshold;
+
public bool TryLogin(string password, out string? compatibilityPasswordUsed)
{
compatibilityPasswordUsed = null;

Add OverridePlebStop to CoinJoinManager