fix changeless coin selector tests
MODIFY
WalletWasabi.Tests/UnitTests/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelectorTests.cs
WalletWasabi.Tests/UnitTests/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelectorTests.cs
@@ -28,10 +28,15 @@ public class ChangelessTransactionCoinSelectorTests
List<SmartCoin> coins = GenerateDummySmartCoins(key, 6_025, 6_561, 8_192, 13_122, 50_000, 100_000, 196_939, 524_288);
var target = Money.Satoshis(150_000);
-
+ var feeRate = new FeeRate(Money.Satoshis(2));
var txOut = new TxOut(target, BitcoinFactory.CreateBitcoinAddress(Network.TestNet, key));
- bool found = ChangelessTransactionCoinSelector.TryGetCoins(SuggestionType.More, coins, new FeeRate(satoshiPerByte: 4), txOut, out IEnumerable<SmartCoin>? selectedCoins);
+ long[] inputCosts = coins.Select(x => feeRate.GetFee(x.ScriptPubKey.EstimateInputVsize()).Satoshi).ToArray();
+
+ Dictionary<SmartCoin, long> inputEffectiveValues = new(coins.ToDictionary(x => x, x => x.EffectiveValue(feeRate).Satoshi));
+ var strategy = new MoreSelectionStrategy(target, inputEffectiveValues.Values.ToArray(), inputCosts);
+
+ bool found = ChangelessTransactionCoinSelector.TryGetCoins(strategy, target, inputEffectiveValues, out var selectedCoins);
Assert.True(found);
long[] solution = selectedCoins!.Select(x => x.Amount.Satoshi).ToArray();
@@ -46,10 +51,17 @@ public class ChangelessTransactionCoinSelectorTests
List<SmartCoin> coins = GenerateDummySmartCoins(key, 6_025, 6_561, 8_192, 13_122, 50_000, 100_000, 196_939, 524_288);
var target = Money.Satoshis(65_000);
+ var feeRate = new FeeRate(Money.Satoshis(2));
var txOut = new TxOut(target, BitcoinFactory.CreateBitcoinAddress(Network.TestNet, key));
- bool found = ChangelessTransactionCoinSelector.TryGetCoins(SuggestionType.Less, coins, new FeeRate(satoshiPerByte: 4), txOut, out IEnumerable<SmartCoin>? selectedCoins);
+ long[] inputCosts = coins.Select(x => feeRate.GetFee(x.ScriptPubKey.EstimateInputVsize()).Satoshi).ToArray();
+
+ Dictionary<SmartCoin, long> inputEffectiveValues = new(coins.ToDictionary(x => x, x => x.EffectiveValue(feeRate).Satoshi));
+
+ var strategy = new LessSelectionStrategy(target, inputEffectiveValues.Values.ToArray(), inputCosts);
+
+ bool found = ChangelessTransactionCoinSelector.TryGetCoins(strategy, target, inputEffectiveValues, out var selectedCoins);
Assert.True(found);
long[] solution = selectedCoins!.Select(x => x.Amount.Satoshi).ToArray();
@@ -66,10 +78,16 @@ public class ChangelessTransactionCoinSelectorTests
List<SmartCoin> coins = GenerateDummySmartCoins(key, 150_000);
var target = Money.Satoshis(100_000);
-
+ var feeRate = new FeeRate(Money.Satoshis(2));
var txOut = new TxOut(target, BitcoinFactory.CreateBitcoinAddress(Network.TestNet, key));
- bool found = ChangelessTransactionCoinSelector.TryGetCoins(SuggestionType.More, coins, new FeeRate(satoshiPerByte: 4), txOut, out IEnumerable<SmartCoin>? selectedCoins);
+ long[] inputCosts = coins.Select(x => feeRate.GetFee(x.ScriptPubKey.EstimateInputVsize()).Satoshi).ToArray();
+
+ Dictionary<SmartCoin, long> inputEffectiveValues = new(coins.ToDictionary(x => x, x => x.EffectiveValue(feeRate).Satoshi));
+
+ var strategy = new LessSelectionStrategy(target, coins.Select(coin => coin.Amount.Satoshi).ToArray(), inputCosts);
+
+ bool found = ChangelessTransactionCoinSelector.TryGetCoins(strategy, target, inputEffectiveValues, out var selectedCoins);
Assert.False(found);
}
@@ -94,6 +112,6 @@ public class ChangelessTransactionCoinSelectorTests
result.Add(new SmartCoin(stx, i, hdPubKey));
}
- return result;
+ return result.OrderByDescending(x => x.Amount.Satoshi).ToList();
}
}

MODIFY
WalletWasabi/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelector.cs
WalletWasabi/Blockchain/TransactionBuilding/ChangelessTransactionCoinSelector.cs
@@ -69,7 +69,7 @@ public static class ChangelessTransactionCoinSelector
/// <param name="target">Target value we want to, ideally, sum up from the input values. </param>
/// <param name="inputEffectiveValues">Dictionary to map back the effective values to their original SmartCoin. </param>
/// <returns><c>true</c> if a solution was found, <c>false</c> otherwise.</returns>
- private static bool TryGetCoins(SelectionStrategy strategy, long target, Dictionary<SmartCoin, long> inputEffectiveValues, [NotNullWhen(true)] out IEnumerable<SmartCoin>? selectedCoins, CancellationToken cancellationToken = default)
+ internal static bool TryGetCoins(SelectionStrategy strategy, long target, Dictionary<SmartCoin, long> inputEffectiveValues, [NotNullWhen(true)] out IEnumerable<SmartCoin>? selectedCoins, CancellationToken cancellationToken = default)
{
selectedCoins = null;

fix changeless coin selector tests