Make `AmountDecomposer` aware output limits
MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Client/AmountDecomposerTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Client/AmountDecomposerTests.cs
@@ -34,8 +34,9 @@ public class AmountDecomposerTests
var feePerOutput = feeRate.GetFee(Constants.P2wpkhOutputSizeInBytes);
var registeredCoinEffectiveValues = GenerateRandomCoins().Take(3).Select(c => c.EffectiveValue(feeRate, CoordinationFeeRate.Zero)).ToList();
var theirCoinEffectiveValues = GenerateRandomCoins().Take(30).Select(c => c.EffectiveValue(feeRate, CoordinationFeeRate.Zero)).ToList();
+ var allowedOutputAmountRange = new MoneyRange(Money.Satoshis(minOutputAmount), Money.Satoshis(ProtocolConstants.MaxAmountPerAlice));
- var amountDecomposer = new AmountDecomposer(feeRate, minOutputAmount, Constants.P2wpkhOutputSizeInBytes, availableVsize);
+ var amountDecomposer = new AmountDecomposer(feeRate, allowedOutputAmountRange, Constants.P2wpkhOutputSizeInBytes, availableVsize);
var outputValues = amountDecomposer.Decompose(registeredCoinEffectiveValues, theirCoinEffectiveValues);
var totalEffectiveValue = registeredCoinEffectiveValues.Sum(x => x);

MODIFY
WalletWasabi/WabiSabi/Client/AmountDecomposer.cs
WalletWasabi/WabiSabi/Client/AmountDecomposer.cs
using System.Collections.Generic;
using System.Linq;
using NBitcoin;
+using WalletWasabi.WabiSabi.Models;
namespace WalletWasabi.WabiSabi.Client;
@@ -10,16 +11,17 @@ namespace WalletWasabi.WabiSabi.Client;
public class AmountDecomposer
{
/// <param name="feeRate">Bitcoin network fee rate the coinjoin is targeting.</param>
- /// <param name="minAllowedOutputAmount">Minimum output amount that's allowed to be registered.</param>
+ /// <param name="allowedOutputAmount">Range of output amount that's allowed to be registered.</param>
/// <param name="outputSize">Size of an output.</param>
/// <param name="availableVsize">Available virtual size for outputs.</param>
- public AmountDecomposer(FeeRate feeRate, Money minAllowedOutputAmount, int outputSize, int availableVsize)
+ public AmountDecomposer(FeeRate feeRate, MoneyRange allowedOutputAmount, int outputSize, int availableVsize)
{
FeeRate = feeRate;
OutputSize = outputSize;
AvailableVsize = availableVsize;
- MinAllowedOutputAmountPlusFee = minAllowedOutputAmount + OutputFee;
+ MinAllowedOutputAmountPlusFee = allowedOutputAmount.Min + OutputFee;
+ MaxAllowedOutputAmount = allowedOutputAmount.Max;
// Create many standard denominations.
DenominationsPlusFees = CreateDenominationsPlusFees();
@@ -28,13 +30,15 @@ public class AmountDecomposer
public FeeRate FeeRate { get; }
public int AvailableVsize { get; }
public Money MinAllowedOutputAmountPlusFee { get; }
+ public Money MaxAllowedOutputAmount { get; }
+
public Money OutputFee => FeeRate.GetFee(OutputSize);
public int OutputSize { get; }
public IOrderedEnumerable<ulong> DenominationsPlusFees { get; }
private IOrderedEnumerable<ulong> CreateDenominationsPlusFees()
{
- ulong maxSatoshis = ProtocolConstants.MaxAmountPerAlice;
+ ulong maxSatoshis = (ulong)MaxAllowedOutputAmount.Satoshi;
ulong minSatoshis = MinAllowedOutputAmountPlusFee;
var denominations = new HashSet<ulong>();

MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinClient.cs
WalletWasabi/WabiSabi/Client/CoinJoinClient.cs
@@ -505,7 +505,7 @@ public class CoinJoinClient
// Calculate outputs values
var constructionState = roundState.Assert<ConstructionState>();
- AmountDecomposer amountDecomposer = new(roundState.FeeRate, roundState.CoinjoinState.Parameters.AllowedOutputAmounts.Min, Constants.P2wpkhOutputSizeInBytes, (int)availableVsize);
+ AmountDecomposer amountDecomposer = new(roundState.FeeRate, roundState.CoinjoinState.Parameters.AllowedOutputAmounts, Constants.P2wpkhOutputSizeInBytes, (int)availableVsize);
var theirCoins = constructionState.Inputs.Except(registeredCoins);
var registeredCoinEffectiveValues = registeredAliceClients.Select(x => x.EffectiveValue);
var theirCoinEffectiveValues = theirCoins.Select(x => x.EffectiveValue(roundState.FeeRate, roundState.CoordinationFeeRate));

Make `AmountDecomposer` aware output limits