show suggestions parallel
MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/ChangeAvoidanceSuggestionViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/ChangeAvoidanceSuggestionViewModel.cs
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using NBitcoin;
@@ -75,8 +76,8 @@ public partial class ChangeAvoidanceSuggestionViewModel : SuggestionViewModel
return normalized;
}
- public static async Task<IEnumerable<ChangeAvoidanceSuggestionViewModel>> GenerateSuggestionsAsync(
- TransactionInfo transactionInfo, BitcoinAddress destination, Wallet wallet, BuildTransactionResult requestedTransaction, CancellationToken cancellationToken)
+ public static async IAsyncEnumerable<ChangeAvoidanceSuggestionViewModel> GenerateSuggestionsAsync(
+ TransactionInfo transactionInfo, BitcoinAddress destination, Wallet wallet, BuildTransactionResult requestedTransaction, [EnumeratorCancellation] CancellationToken cancellationToken)
{
var intent = new PaymentIntent(
destination,
@@ -105,41 +106,29 @@ public partial class ChangeAvoidanceSuggestionViewModel : SuggestionViewModel
wallet.Synchronizer.UsdExchangeRate, false);
}
- ChangeAvoidanceSuggestionViewModel? bnbSuggestion = null;
- IEnumerable<SmartCoin>? bnbResult = null;
- bool canBuildWithoutChangeWithBnb = false;
-
- try
- {
- canBuildWithoutChangeWithBnb = await Task.Run(() => ChangelessTransactionCoinSelector.TryGetCoins(wallet.Coins.Available().ToList(), transactionInfo.FeeRate, transactionInfo.Amount, out bnbResult, cancellationToken));
- }
- catch (OperationCanceledException)
+ Task<ChangeAvoidanceSuggestionViewModel?> bnbSuggestionTask = Task.Run(() =>
{
- Logger.LogInfo("Changeless Coin Selector timed out.");
- }
+ List<SmartCoin> availableCoins = wallet.Coins.Available().ToList();
- if (canBuildWithoutChangeWithBnb && bnbResult is not null)
+ if (ChangelessTransactionCoinSelector.TryGetCoins(availableCoins, transactionInfo.FeeRate, transactionInfo.Amount, out IEnumerable<SmartCoin>? selection, cancellationToken))
{
- var bnbTransaction = await Task.Run(() => TransactionHelpers.BuildChangelessTransaction(
+ var transaction = TransactionHelpers.BuildChangelessTransaction(
wallet,
destination,
transactionInfo.UserLabels,
transactionInfo.FeeRate,
- bnbResult,
- tryToSign: false
- ));
+ selection,
+ tryToSign: false);
- bnbSuggestion = new ChangeAvoidanceSuggestionViewModel(
+ return new ChangeAvoidanceSuggestionViewModel(
transactionInfo.Amount.ToDecimal(MoneyUnit.BTC),
- bnbTransaction,
+ transaction,
wallet.Synchronizer.UsdExchangeRate,
- isOriginal: false
- );
+ isOriginal: false);
}
- var defaultSelection = new ChangeAvoidanceSuggestionViewModel(
- transactionInfo.Amount.ToDecimal(MoneyUnit.BTC), requestedTransaction,
- wallet.Synchronizer.UsdExchangeRate, true);
+ return null;
+ });
var largerTransaction = await Task.Run(() => wallet.BuildTransaction(
wallet.Kitchen.SaltSoup(),
@@ -154,28 +143,21 @@ public partial class ChangeAvoidanceSuggestionViewModel : SuggestionViewModel
transactionInfo.Amount.ToDecimal(MoneyUnit.BTC), largerTransaction,
wallet.Synchronizer.UsdExchangeRate, false);
- // There are several scenarios, both the alternate suggestions are <, or >, or 1 < and 1 >.
- // We sort them and add the suggestions accordingly.
- var suggestions = new List<ChangeAvoidanceSuggestionViewModel> { defaultSelection, largerSuggestion };
-
- if (smallerSuggestion is { })
+ if (smallerSuggestion is not null)
{
- suggestions.Add(smallerSuggestion);
+ yield return smallerSuggestion;
}
- if (bnbSuggestion is not null)
+ if (largerSuggestion is not null)
{
- suggestions.Add(bnbSuggestion);
+ yield return largerSuggestion;
}
- var results = new List<ChangeAvoidanceSuggestionViewModel>();
+ ChangeAvoidanceSuggestionViewModel? bnbSuggestion = await bnbSuggestionTask;
- foreach (var suggestion in NormalizeSuggestions(suggestions, defaultSelection)
- .Where(x => x != defaultSelection))
+ if (bnbSuggestion is not null)
{
- results.Add(suggestion);
+ yield return bnbSuggestion;
}
-
- return results;
}
}

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacySuggestionsFlyoutViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/PrivacySuggestionsFlyoutViewModel.cs
@@ -51,9 +51,9 @@ public partial class PrivacySuggestionsFlyoutViewModel : ViewModelBase
if (hasChange)
{
var suggestions =
- await ChangeAvoidanceSuggestionViewModel.GenerateSuggestionsAsync(info, destination, wallet, transaction, cancellationToken);
+ ChangeAvoidanceSuggestionViewModel.GenerateSuggestionsAsync(info, destination, wallet, transaction, cancellationToken);
- foreach (var suggestion in suggestions)
+ await foreach (var suggestion in suggestions)
{
Suggestions.Add(suggestion);
}

show suggestions parallel