Document it more.
MODIFY
WalletWasabi.Tests/UnitTests/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelectorTests.cs
WalletWasabi.Tests/UnitTests/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelectorTests.cs
@@ -17,8 +17,11 @@ namespace WalletWasabi.Tests.UnitTests.Blockchain.TransactionBuilding;
/// </summary>
public class ChangelessTransactionCoinSelectorTests
{
+ /// <summary>
+ /// Tests that we select coins so that user can agree with paying more money for having a payment transaction with no change output.
+ /// </summary>
[Fact]
- public void FindBestSolution()
+ public void TryGetCoins()
{
using Key key = new();
@@ -33,6 +36,7 @@ public class ChangelessTransactionCoinSelectorTests
Assert.Equal(6025, solution.Sum() - target); // ~4% more for the privacy.
}
+ /// <remarks>These smart coins are from an invalid transaction but we are interested only in smart coins' amounts.</remarks>
private List<SmartCoin> GenerateDummySmartCoins(Key key, params long[] values)
{
Network network = Network.Main;

MODIFY
WalletWasabi/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelector.cs
WalletWasabi/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelector.cs
@@ -10,6 +10,18 @@ namespace WalletWasabi.Blockchain.TransactionBuilding;
public static class ChangelessTransactionCoinSelector
{
+ /// <summary>
+ /// Select coins in a way that user can pay without a change input (to increase privacy)
+ /// and try to find a solution that requires to pay as little extra amount as possible.
+ /// </summary>
+ /// <param name="availableCoins">Coins owned by the user.</param>
+ /// <param name="feeRate">Current fee rate to take into account effective values of available coins.</param>
+ /// <param name="target">Amount the user wants to pay in satoshis.</param>
+ /// <returns><c>true</c> if a solution was found, <c>false</c> otherwise.</returns>
+ /// <remarks>
+ /// The implementation does not give any guarantee how much extra amount we can pay. It's a responsibility of the caller
+ /// to judge what is "too much" (e.g. paying $15 for a $5 dollar coffee seems excessive for majority of people but some may still want to do it.)
+ /// </remarks>
public static bool TryGetCoins(List<SmartCoin> availableCoins, FeeRate feeRate, long target, [NotNullWhen(true)] out List<SmartCoin>? selectedCoins, CancellationToken cancellationToken = default)
{
selectedCoins = null;
@@ -18,7 +30,7 @@ public static class ChangelessTransactionCoinSelector
Dictionary<SmartCoin, long> inputs = new(sortedCoins.ToDictionary(x => x, x => x.EffectiveValue(feeRate).Satoshi));
- // Pass smart coins' effective values in ascending order.
+ // Pass smart coins' effective values in descending order.
BranchAndBound branchAndBound = new(inputs.Values.ToList());
PruneByBestStrategy strategy = new(target);

Document it more.