Provide reason for remove coins
MODIFY
WalletWasabi.Gui/CommandLine/Daemon.cs
WalletWasabi.Gui/CommandLine/Daemon.cs
@@ -199,7 +199,7 @@ namespace WalletWasabi.Gui.CommandLine
mixing = anyCoinsQueued || keepMixAlive;
} while (mixing);
- await Global.ChaumianClient.DequeueAllCoinsFromMixAsync();
+ await Global.ChaumianClient.DequeueAllCoinsFromMixAsync("Stopping Wasabi");
}
return continueWithGui;

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/CoinJoinTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/CoinJoinTabViewModel.cs
@@ -194,7 +194,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
try
{
- await Global.ChaumianClient.DequeueCoinsFromMixAsync(selectedCoins.Select(c => c.Model).ToArray());
+ await Global.ChaumianClient.DequeueCoinsFromMixAsync(selectedCoins.Select(c => c.Model).ToArray(), "Dequeued by user");
}
catch (Exception ex)
{

MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/SendTabViewModel.cs
@@ -243,7 +243,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
TxoRef[] toDequeue = selectedCoinViewModels.Where(x => x.CoinJoinInProgress).Select(x => x.Model.GetTxoRef()).ToArray();
if (toDequeue != null && toDequeue.Any())
{
- await Global.ChaumianClient.DequeueCoinsFromMixAsync(toDequeue);
+ await Global.ChaumianClient.DequeueCoinsFromMixAsync(toDequeue, "Coin used in spending transaction built by the user");
}
}
catch
@@ -592,7 +592,7 @@ namespace WalletWasabi.Gui.Controls.WalletExplorer
try
{
- await Global.ChaumianClient.DequeueCoinsFromMixAsync(selectedCoins.Select(c => c.Model).ToArray());
+ await Global.ChaumianClient.DequeueCoinsFromMixAsync(selectedCoins.Select(c => c.Model).ToArray(), "Dequeued by the user");
}
catch (Exception ex)
{

MODIFY
WalletWasabi.Gui/Dialogs/CannotCloseDialogViewModel.cs
WalletWasabi.Gui/Dialogs/CannotCloseDialogViewModel.cs
@@ -148,7 +148,7 @@ namespace WalletWasabi.Gui.Dialogs
break;
}
- await Global.ChaumianClient.DequeueCoinsFromMixAsync(new SmartCoin[] { coin }); //dequeue coins one-by-one to check cancel flag more frequently
+ await Global.ChaumianClient.DequeueCoinsFromMixAsync(new SmartCoin[] { coin }, "Dequeued to close Wasabi"); //dequeue coins one-by-one to check cancel flag more frequently
}
catch (Exception ex)
{

MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -108,7 +108,7 @@ namespace WalletWasabi.Gui
if (enqueuedCoins.Any())
{
Logger.LogWarning("Unregistering coins in CoinJoin process.", nameof(Global));
- await ChaumianClient.DequeueCoinsFromMixAsync(enqueuedCoins);
+ await ChaumianClient.DequeueCoinsFromMixAsync(enqueuedCoins, "Dequeued in desperate mode to respond to process exit");
}
}

MODIFY
WalletWasabi.Tests/RegTests.cs
WalletWasabi.Tests/RegTests.cs
@@ -3101,7 +3101,7 @@ namespace WalletWasabi.Tests
if (chaumianClient != null)
{
- await chaumianClient.DequeueAllCoinsFromMixAsync();
+ await chaumianClient.DequeueAllCoinsFromMixAsync("No reason given");
await chaumianClient.StopAsync();
}
}
@@ -3183,19 +3183,19 @@ namespace WalletWasabi.Tests
Assert.True(smartCoin2.CoinJoinInProgress);
// Make sure it doesn't throw.
- await chaumianClient1.DequeueCoinsFromMixAsync(new SmartCoin((network.Consensus.ConsensusFactory.CreateTransaction()).GetHash(), 1, new Script(), Money.Parse("3"), new TxoRef[] { new TxoRef((network.Consensus.ConsensusFactory.CreateTransaction()).GetHash(), 0) }, Height.MemPool, replaceable: false, anonymitySet: 1));
+ await chaumianClient1.DequeueCoinsFromMixAsync(new SmartCoin((network.Consensus.ConsensusFactory.CreateTransaction()).GetHash(), 1, new Script(), Money.Parse("3"), new TxoRef[] { new TxoRef((network.Consensus.ConsensusFactory.CreateTransaction()).GetHash(), 0) }, Height.MemPool, replaceable: false, anonymitySet: 1), string.Empty);
Assert.True(2 == (await chaumianClient1.QueueCoinsToMixAsync(password, smartCoin1, smartCoin2)).Count());
- await chaumianClient1.DequeueCoinsFromMixAsync(smartCoin1);
+ await chaumianClient1.DequeueCoinsFromMixAsync(smartCoin1, string.Empty);
Assert.False(smartCoin1.CoinJoinInProgress);
- await chaumianClient1.DequeueCoinsFromMixAsync(smartCoin1, smartCoin2);
+ await chaumianClient1.DequeueCoinsFromMixAsync(new []{smartCoin1, smartCoin2}, string.Empty);
Assert.False(smartCoin1.CoinJoinInProgress);
Assert.False(smartCoin2.CoinJoinInProgress);
Assert.True(2 == (await chaumianClient1.QueueCoinsToMixAsync(password, smartCoin1, smartCoin2)).Count());
Assert.True(smartCoin1.CoinJoinInProgress);
Assert.True(smartCoin2.CoinJoinInProgress);
- await chaumianClient1.DequeueCoinsFromMixAsync(smartCoin1);
- await chaumianClient1.DequeueCoinsFromMixAsync(smartCoin2);
+ await chaumianClient1.DequeueCoinsFromMixAsync(smartCoin1, string.Empty);
+ await chaumianClient1.DequeueCoinsFromMixAsync(smartCoin2, string.Empty);
Assert.False(smartCoin1.CoinJoinInProgress);
Assert.False(smartCoin2.CoinJoinInProgress);
@@ -3225,7 +3225,7 @@ namespace WalletWasabi.Tests
coordinator.UpdateRoundConfig(roundConfig);
coordinator.AbortAllRoundsInInputRegistration(nameof(RegTests), "");
Assert.NotEmpty(chaumianClient1.State.GetAllQueuedCoins());
- await chaumianClient1.DequeueAllCoinsFromMixAsync();
+ await chaumianClient1.DequeueAllCoinsFromMixAsync(string.Empty);
Assert.Empty(chaumianClient1.State.GetAllQueuedCoins());
await chaumianClient1.QueueCoinsToMixAsync(password, smartCoin4);
Assert.NotEmpty(chaumianClient1.State.GetAllQueuedCoins());
@@ -3403,7 +3403,7 @@ namespace WalletWasabi.Tests
}
}
SmartCoin[] unspentChanges = wallet.Coins.Where(x => x.Label == "ZeroLink Change" && x.Unspent).ToArray();
- await wallet.ChaumianClient.DequeueCoinsFromMixAsync(unspentChanges);
+ await wallet.ChaumianClient.DequeueCoinsFromMixAsync(unspentChanges, string.Empty);
Assert.Equal(3, wallet.Coins.Count(x => x.Label == "ZeroLink Mixed Coin" && !x.Unavailable));
Assert.Equal(3, wallet2.Coins.Count(x => x.Label == "ZeroLink Mixed Coin" && !x.Unavailable));

MODIFY
WalletWasabi/Services/CcjClient.cs
WalletWasabi/Services/CcjClient.cs
@@ -230,7 +230,7 @@ namespace WalletWasabi.Services
if (!registrableRound.State.HaveEnoughQueued(State.GetAllQueuedCoinAmounts().ToArray())
|| dequeueBecauseCoordinatorFeeChanged)
{
- await DequeueAllCoinsFromMixNoLockAsync();
+ await DequeueAllCoinsFromMixNoLockAsync("Registered coins total value is not enough or coordinator's fee changed");
}
}
}
@@ -559,7 +559,7 @@ namespace WalletWasabi.Services
Logger.LogWarning<CcjClient>(ex.Message.Split('\n')[1]);
- await DequeueCoinsFromMixNoLockAsync(coinReference);
+ await DequeueCoinsFromMixNoLockAsync(coinReference, "Failed to register the coin with the coordinator");
aliceClient?.Dispose();
return;
}
@@ -579,7 +579,7 @@ namespace WalletWasabi.Services
Logger.LogWarning<CcjClient>(ex.Message.Split('\n')[1]);
- await DequeueCoinsFromMixNoLockAsync(coinReference);
+ await DequeueCoinsFromMixNoLockAsync(coinReference, "Failed to register the coin with the coordinator. The coin is already spent.");
aliceClient?.Dispose();
return;
}
@@ -805,7 +805,13 @@ namespace WalletWasabi.Services
return successful;
}
- public async Task DequeueCoinsFromMixAsync(params SmartCoin[] coins)
+ public async Task DequeueCoinsFromMixAsync(SmartCoin coin, string reason)
+ {
+ await DequeueCoinsFromMixAsync(new []{ coin }, reason);
+
+ }
+
+ public async Task DequeueCoinsFromMixAsync(IEnumerable<SmartCoin> coins, string reason)
{
if (coins is null || !coins.Any())
{
@@ -820,14 +826,14 @@ namespace WalletWasabi.Services
{
await DequeueSpentCoinsFromMixNoLockAsync();
- await DequeueCoinsFromMixNoLockAsync(coins.Select(x => x.GetTxoRef()).ToArray());
+ await DequeueCoinsFromMixNoLockAsync(coins.Select(x => x.GetTxoRef()).ToArray(), reason);
}
}
catch (TaskCanceledException)
{
- await DequeueCoinsFromMixNoLockAsync(State.GetSpentCoins().ToArray());
+ await DequeueCoinsFromMixNoLockAsync(State.GetSpentCoins().ToArray(), reason);
- await DequeueCoinsFromMixNoLockAsync(coins.Select(x => x.GetTxoRef()).ToArray());
+ await DequeueCoinsFromMixNoLockAsync(coins.Select(x => x.GetTxoRef()).ToArray(), reason);
}
}
}
@@ -863,7 +869,12 @@ namespace WalletWasabi.Services
}
}
- public async Task DequeueCoinsFromMixAsync(params TxoRef[] coins)
+ public async Task DequeueCoinsFromMixAsync(TxoRef coin, string reason)
+ {
+ await DequeueCoinsFromMixAsync(new[] { coin }, reason);
+ }
+
+ public async Task DequeueCoinsFromMixAsync(TxoRef[] coins, string reason)
{
if (coins is null || !coins.Any())
{
@@ -878,19 +889,19 @@ namespace WalletWasabi.Services
{
await DequeueSpentCoinsFromMixNoLockAsync();
- await DequeueCoinsFromMixNoLockAsync(coins);
+ await DequeueCoinsFromMixNoLockAsync(coins, reason);
}
}
catch (TaskCanceledException)
{
await DequeueSpentCoinsFromMixNoLockAsync();
- await DequeueCoinsFromMixNoLockAsync(coins);
+ await DequeueCoinsFromMixNoLockAsync(coins, reason);
}
}
}
- public async Task DequeueAllCoinsFromMixAsync()
+ public async Task DequeueAllCoinsFromMixAsync(string reason)
{
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
{
@@ -898,19 +909,19 @@ namespace WalletWasabi.Services
{
using (await MixLock.LockAsync(cts.Token))
{
- await DequeueAllCoinsFromMixNoLockAsync();
+ await DequeueAllCoinsFromMixNoLockAsync(reason);
}
}
catch (TaskCanceledException)
{
- await DequeueAllCoinsFromMixNoLockAsync();
+ await DequeueAllCoinsFromMixNoLockAsync(reason);
}
}
}
- private async Task DequeueAllCoinsFromMixNoLockAsync()
+ private async Task DequeueAllCoinsFromMixNoLockAsync(string reason)
{
- await DequeueCoinsFromMixNoLockAsync(State.GetAllQueuedCoins().ToArray());
+ await DequeueCoinsFromMixNoLockAsync(State.GetAllQueuedCoins().ToArray(), reason);
}
private async Task DequeueSpentCoinsFromMixNoLockAsync()
@@ -918,7 +929,12 @@ namespace WalletWasabi.Services
await DequeueCoinsFromMixNoLockAsync(State.GetSpentCoins().ToArray());
}
- private async Task DequeueCoinsFromMixNoLockAsync(params TxoRef[] coins)
+ private async Task DequeueCoinsFromMixNoLockAsync(TxoRef coin, string reason=null)
+ {
+ await DequeueCoinsFromMixNoLockAsync(new []{ coin }, reason);
+ }
+
+ private async Task DequeueCoinsFromMixNoLockAsync(TxoRef[] coins, string reason=null)
{
if (coins is null || !coins.Any())
{
@@ -985,7 +1001,7 @@ namespace WalletWasabi.Services
SmartCoin coinWaitingForMix = State.GetSingleOrDefaultFromWaitingList(coinToDequeue);
if (coinWaitingForMix != null) // If it is not being mixed, we can just remove it.
{
- RemoveCoin(coinWaitingForMix);
+ RemoveCoin(coinWaitingForMix, reason);
}
}
@@ -1000,7 +1016,7 @@ namespace WalletWasabi.Services
}
}
- private void RemoveCoin(SmartCoin coinWaitingForMix)
+ private void RemoveCoin(SmartCoin coinWaitingForMix, string reason=null)
{
State.RemoveCoinFromWaitingList(coinWaitingForMix);
coinWaitingForMix.CoinJoinInProgress = false;
@@ -1015,7 +1031,8 @@ namespace WalletWasabi.Services
}
}
CoinDequeued?.Invoke(this, coinWaitingForMix);
- Logger.LogInfo<CcjClient>($"Coin dequeued: {coinWaitingForMix.Index}:{coinWaitingForMix.TransactionId}.");
+ var reasonText = reason != null ? $"Reason: {reason}." : string.Empty;
+ Logger.LogInfo<CcjClient>($"Coin dequeued: {coinWaitingForMix.Index}:{coinWaitingForMix.TransactionId}. {reasonText}");
}
public async Task StopAsync()
@@ -1047,7 +1064,7 @@ namespace WalletWasabi.Services
{
continue; // The coin isn't present anymore. Good. This should never happen though.
}
- await DequeueCoinsFromMixNoLockAsync(coin.GetTxoRef());
+ await DequeueCoinsFromMixNoLockAsync(coin.GetTxoRef(), "Stopping Wasabi");
}
catch (Exception ex)
{

Provide reason for remove coins