Refactor Effective Value
MODIFY
WalletWasabi/Extensions/NBitcoinExtensions.cs
WalletWasabi/Extensions/NBitcoinExtensions.cs
@@ -464,6 +464,12 @@ namespace NBitcoin
false => throw new NotImplementedException($"Size estimation isn't implemented for provided script type.")
};
+ public static Money EffectiveValue(this TxOut output, FeeRate feeRate) =>
+ output.Value - feeRate.GetFee(output.ScriptPubKey.EstimateOutputVsize());
+
+ public static Money EffectiveValue(this Coin coin, FeeRate feeRate) =>
+ coin.Amount - feeRate.GetFee(coin.ScriptPubKey.EstimateInputVsize());
+
public static T FromBytes<T>(byte[] input) where T : IBitcoinSerializable, new()
{
BitcoinStream inputStream = new(input);

MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinClient.cs
WalletWasabi/WabiSabi/Client/CoinJoinClient.cs
@@ -70,8 +70,8 @@ namespace WalletWasabi.WabiSabi.Client
// Re-issuances.
DependencyGraph dependencyGraph = DependencyGraph.ResolveCredentialDependencies(aliceClients.Select(a => a.Coin), outputTxOuts, roundState.FeeRate);
- var bobClient = CreateBobClient(roundState);
DependencyGraphResolver dgr = new(dependencyGraph);
+ var bobClient = CreateBobClient(roundState);
var outputCredentials = await dgr.ResolveAsync(aliceClients, bobClient, cancellationToken).ConfigureAwait(false);
// Output registration.
@@ -84,7 +84,7 @@ namespace WalletWasabi.WabiSabi.Client
var unsignedCoinJoin = signingState.CreateUnsignedTransaction();
// Sanity check.
- var effectiveOutputs = outputTxOuts.Select(o => (o.Value - roundState.FeeRate.GetFee(o.ScriptPubKey.EstimateOutputVsize()), o.ScriptPubKey));
+ var effectiveOutputs = outputTxOuts.Select(o => (o.EffectiveValue(roundState.FeeRate), o.ScriptPubKey));
if (!SanityCheck(effectiveOutputs, unsignedCoinJoin))
{
throw new InvalidOperationException($"Round ({roundState.Id}): My output is missing.");
@@ -159,7 +159,7 @@ namespace WalletWasabi.WabiSabi.Client
{
var allDenominations = BaseDenominationGenerator.Generate();
GreedyDecomposer greedyDecomposer = new(allDenominations);
- var amounts = Coins.Select(c => c.Amount - feeRate.GetFee(c.ScriptPubKey.EstimateInputVsize()));
+ var amounts = Coins.Select(c => c.EffectiveValue(feeRate));
var denominations = greedyDecomposer.Decompose(amounts.Sum());
return amounts;
}

MODIFY
WalletWasabi/WabiSabi/Client/CredentialDependencies/DependencyGraph.cs
WalletWasabi/WabiSabi/Client/CredentialDependencies/DependencyGraph.cs
@@ -49,7 +49,7 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
public static DependencyGraph ResolveCredentialDependencies(IEnumerable<Coin> inputs, IEnumerable<TxOut> outputs, FeeRate feerate)
{
var inputSizes = inputs.Select(x => x.ScriptPubKey.EstimateInputVsize());
- var effectiveValues = Enumerable.Zip(inputs, inputSizes, (coin, size) => coin.Amount - feerate.GetFee(size));
+ var effectiveValues = Enumerable.Zip(inputs, inputSizes, (coin, size) => coin.EffectiveValue(feerate));
if (effectiveValues.Any(x => x <= Money.Zero))
{
@@ -57,7 +57,7 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
}
var outputSizes = outputs.Select(x => x.ScriptPubKey.EstimateOutputVsize());
- var effectiveCosts = Enumerable.Zip(outputs, outputSizes, (txout, size) => txout.Value - feerate.GetFee(size));
+ var effectiveCosts = Enumerable.Zip(outputs, outputSizes, (txout, size) => txout.EffectiveValue(feerate));
return ResolveCredentialDependencies(
Enumerable.Zip(effectiveValues.Select(a => (ulong)a.Satoshi), inputSizes.Select(i => (ulong)i), ImmutableArray.Create).Cast<IEnumerable<ulong>>(),

Refactor Effective Value