Add Coordinator fee calculation
MODIFY
WalletWasabi/ChaumianCoinJoin/Alice.cs
WalletWasabi/ChaumianCoinJoin/Alice.cs
@@ -21,7 +21,7 @@ namespace WalletWasabi.ChaumianCoinJoin
public Script ChangeOutputScript { get; }
- public Money GetChangeAmount(Money denomination) => OutputSum - denomination;
+ public Money GetChangeAmount(Money denomination, Money coordinatorFee) => OutputSum - denomination - coordinatorFee;
public Alice(Dictionary<OutPoint, TxOut> inputs, Money feeToPay, Script changeOutputScript)
{

MODIFY
WalletWasabi/ChaumianCoinJoin/CcjRound.cs
WalletWasabi/ChaumianCoinJoin/CcjRound.cs
@@ -20,7 +20,7 @@ namespace WalletWasabi.ChaumianCoinJoin
public Money Denomination { get; }
public int ConfirmationTarget { get; }
- public Money CoordinatorFee { get; }
+ public decimal CoordinatorFeePercent { get; }
public int AnonymitySet { get; private set; }
public Money FeePerInputs { get; private set; }
@@ -50,7 +50,7 @@ namespace WalletWasabi.ChaumianCoinJoin
Denomination = config.Denomination;
ConfirmationTarget = (int)config.ConfirmationTarget;
- CoordinatorFee = new Money(((decimal)config.CoordinatorFeePercent * 0.01m) * decimal.Parse(Denomination.ToString(false, true)), MoneyUnit.BTC);
+ CoordinatorFeePercent = (decimal)CoordinatorFeePercent;
AnonymitySet = (int)config.AnonymitySet;
Phase = CcjRoundPhase.InputRegistration;
@@ -140,13 +140,17 @@ namespace WalletWasabi.ChaumianCoinJoin
transaction.AddOutput(newDenomination, bob.ActiveOutputScript);
}
+ BitcoinWitPubKeyAddress coordinatorAddress = Constants.GetCoordinatorAddress(RpcClient.Network);
// 3. If there are less Bobs than Alices, then add our own address. The malicious Alice, who will refuse to sign.
for (int i = 0; i < Alices.Count - Bobs.Count; i++)
{
- var donation = Constants.GetFailedZeroLinkDosAttackAddress(RpcClient.Network);
- transaction.AddOutput(Denomination, donation);
+ transaction.AddOutput(newDenomination, coordinatorAddress);
}
+ // 4. Add Coordinator fee.
+ Money coordinatorFeePerAlice = new Money((CoordinatorFeePercent * 0.01m) * decimal.Parse(newDenomination.ToString(false, true)), MoneyUnit.BTC);
+ transaction.AddOutput(Alices.Count * coordinatorFeePerAlice, coordinatorAddress);
+
// 4. Add the inputs and the changes of Alices.
foreach (Alice alice in Alices)
{
@@ -154,7 +158,7 @@ namespace WalletWasabi.ChaumianCoinJoin
{
transaction.AddInput(new TxIn(input.Key));
}
- transaction.AddOutput(alice.GetChangeAmount(newDenomination), alice.ChangeOutputScript);
+ transaction.AddOutput(alice.GetChangeAmount(newDenomination, coordinatorFeePerAlice), alice.ChangeOutputScript);
}
// 5. Create the unsigned transaction.

MODIFY
WalletWasabi/Helpers/Constants.cs
WalletWasabi/Helpers/Constants.cs
@@ -14,22 +14,22 @@ namespace WalletWasabi.Helpers
// There are a maximum of 2,099,999,997,690,000 Bitcoin elements (called satoshis), which are currently most commonly measured in units of 100,000,000 known as BTC. Stated another way, no more than 21 million BTC can ever be created.
public const long MaximumNumberOfSatoshis = 2099999997690000;
- public static BitcoinWitPubKeyAddress GetFailedZeroLinkDosAttackAddress(Network network)
+ public static BitcoinWitPubKeyAddress GetCoordinatorAddress(Network network)
{
Guard.NotNull(nameof(network), network);
if(network == Network.Main)
{
- return new BitcoinWitPubKeyAddress("bc1qamgq88h3lylcyesjkc5jjr8rc80le78lltn7ld", Network.Main);
+ return new BitcoinWitPubKeyAddress("bc1qs604c7jv6amk4cxqlnvuxv26hv3e48cds4m0ew", Network.Main);
}
if (network == Network.TestNet)
{
- return new BitcoinWitPubKeyAddress("tb1qxflvleexdwqjtcmxmwjy8fueaf3rux03lrg3qk", Network.TestNet);
+ return new BitcoinWitPubKeyAddress("tb1qecaheev3hjzs9a3w9x33wr8n0ptu7txp359exs", Network.TestNet);
}
// else regtest
- return new BitcoinWitPubKeyAddress("bcrt1q2gqv6rnarkmprd2wgtmkgh5wte4ungapgazess", Network.RegTest);
+ return new BitcoinWitPubKeyAddress("bcrt1qangxrwyej05x9mnztkakk29s4yfdv4n586gs8l", Network.RegTest);
}
}
}

Add Coordinator fee calculation