Create ActiveOutput class (instead of the touple we used previously.)
MODIFY
WalletWasabi.Tests/RegTests.cs
WalletWasabi.Tests/RegTests.cs
@@ -2267,7 +2267,7 @@ namespace WalletWasabi.Tests
var roundState = await satoshiClient.GetRoundStateAsync(aliceClient1.RoundId);
Assert.Equal(CcjRoundPhase.OutputRegistration, roundState.Phase);
- if (!round.MixingLevels.GetBaseLevel().Signer.VerifyUnblindedSignature(connConfResp2.activeOutputs.First().signature, outputAddress2.ScriptPubKey.ToBytes()))
+ if (!round.MixingLevels.GetBaseLevel().Signer.VerifyUnblindedSignature(connConfResp2.activeOutputs.First().Signature, outputAddress2.ScriptPubKey.ToBytes()))
{
throw new NotSupportedException("Coordinator did not sign the blinded output properly.");
}
@@ -2275,8 +2275,8 @@ namespace WalletWasabi.Tests
using (var bobClient1 = new BobClient(baseUri, null))
using (var bobClient2 = new BobClient(baseUri, null))
{
- await bobClient1.PostOutputAsync(aliceClient1.RoundId, outputAddress1, connConfResp.activeOutputs.First().signature, 0);
- await bobClient2.PostOutputAsync(aliceClient2.RoundId, outputAddress2, connConfResp2.activeOutputs.First().signature, 0);
+ await bobClient1.PostOutputAsync(aliceClient1.RoundId, new ActiveOutput(outputAddress1, connConfResp.activeOutputs.First().Signature, 0));
+ await bobClient2.PostOutputAsync(aliceClient2.RoundId, new ActiveOutput(outputAddress2, connConfResp2.activeOutputs.First().Signature, 0));
}
roundState = await satoshiClient.GetRoundStateAsync(aliceClient1.RoundId);
@@ -2436,7 +2436,7 @@ namespace WalletWasabi.Tests
}
// CONNECTION CONFIRMATION PHASE --
- var activeOutputs = new List<IEnumerable<(BitcoinAddress output, UnblindedSignature signature, int level)>>();
+ var activeOutputs = new List<IEnumerable<ActiveOutput>>();
var j = 0;
foreach (var (aliceClient, _, _) in participants)
{
@@ -2457,7 +2457,7 @@ namespace WalletWasabi.Tests
var i = 0;
foreach (var output in outputs.Take(activeOutputs[l].Count()))
{
- await bobClient.PostOutputAsync(aliceClient.RoundId, output.outputAddress, activeOutputs[l].ElementAt(i).signature, i);
+ await bobClient.PostOutputAsync(aliceClient.RoundId, new ActiveOutput(output.outputAddress, activeOutputs[l].ElementAt(i).Signature, i));
i++;
}
}
@@ -2685,7 +2685,7 @@ namespace WalletWasabi.Tests
Assert.Equal(users.Count, roundConfig.AnonymitySet);
- var confirmationRequests = new List<Task<(CcjRoundPhase currentPhase, IEnumerable<(BitcoinAddress output, UnblindedSignature signature, int level)>)>>();
+ var confirmationRequests = new List<Task<(CcjRoundPhase currentPhase, IEnumerable<ActiveOutput>)>>();
foreach (var user in users)
{
@@ -2707,7 +2707,7 @@ namespace WalletWasabi.Tests
}
var user = users.ElementAt(k);
- user.unblindedSignature = resp.Item2.First().signature;
+ user.unblindedSignature = resp.Item2.First().Signature;
}
using (var satoshiClient = new SatoshiClient(baseUri, null))
@@ -2756,7 +2756,7 @@ namespace WalletWasabi.Tests
Assert.Equal(users.Count, roundConfig.AnonymitySet);
- confirmationRequests = new List<Task<(CcjRoundPhase currentPhase, IEnumerable<(BitcoinAddress output, UnblindedSignature signature, int level)>)>>();
+ confirmationRequests = new List<Task<(CcjRoundPhase currentPhase, IEnumerable<ActiveOutput>)>>();
foreach (var user in users)
{
@@ -2889,7 +2889,7 @@ namespace WalletWasabi.Tests
Logger.TurnOn();
Assert.Equal(users.Count, roundConfig.AnonymitySet);
- var confirmationRequests = new List<Task<(CcjRoundPhase currentPhase, IEnumerable<(BitcoinAddress output, UnblindedSignature signature, int level)>)>>();
+ var confirmationRequests = new List<Task<(CcjRoundPhase currentPhase, IEnumerable<ActiveOutput>)>>();
foreach (var user in users)
{
@@ -2913,14 +2913,14 @@ namespace WalletWasabi.Tests
// Because it's valuetuple.
var user = users.ElementAt(k);
users.RemoveAt(k);
- users.Add((user.requester, user.blinded, user.activeOutputAddress, user.changeOutputAddress, user.inputProofModels, user.userInputData, user.aliceClient, resp.Item2.First().signature));
+ users.Add((user.requester, user.blinded, user.activeOutputAddress, user.changeOutputAddress, user.inputProofModels, user.userInputData, user.aliceClient, resp.Item2.First().Signature));
}
var outputRequests = new List<(BobClient, Task)>();
foreach (var user in users)
{
var bobClient = new BobClient(baseUri, null);
- outputRequests.Add((bobClient, bobClient.PostOutputAsync(roundId, user.activeOutputAddress, user.unblindedSignature, 0)));
+ outputRequests.Add((bobClient, bobClient.PostOutputAsync(roundId, new ActiveOutput(user.activeOutputAddress, user.unblindedSignature, 0))));
}
foreach (var request in outputRequests)

ADD
WalletWasabi/Models/ChaumianCoinJoin/ActiveOutput.cs
+using NBitcoin;
+using NBitcoin.Crypto;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using WalletWasabi.Helpers;
+
+namespace WalletWasabi.Models.ChaumianCoinJoin
+{
+ public class ActiveOutput
+ {
+ public BitcoinAddress Address { get; }
+ public UnblindedSignature Signature { get; }
+ public int MixingLevel { get; }
+
+ public ActiveOutput(BitcoinAddress address, UnblindedSignature signature, int mixingLevel)
+ {
+ Address = Guard.NotNull(nameof(address), address);
+ Signature = Guard.NotNull(nameof(signature), signature);
+ MixingLevel = Guard.MinimumAndNotNull(nameof(mixingLevel), mixingLevel, 0);
+ }
+ }
+}

MODIFY
WalletWasabi/Models/ChaumianCoinJoin/ClientRoundRegistration.cs
WalletWasabi/Models/ChaumianCoinJoin/ClientRoundRegistration.cs
@@ -19,7 +19,7 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
public BitcoinAddress ChangeAddress { get; }
- public IEnumerable<(BitcoinAddress address, UnblindedSignature signature, int mixingLevel)> ActiveOutputs { get; set; }
+ public IEnumerable<ActiveOutput> ActiveOutputs { get; set; }
public IEnumerable<SmartCoin> CoinsRegistered { get; }
@@ -31,7 +31,7 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
CoinsRegistered = Guard.NotNullOrEmpty(nameof(coinsRegistereds), coinsRegistereds);
ChangeAddress = Guard.NotNull(nameof(changeAddress), changeAddress);
- ActiveOutputs = Enumerable.Empty<(BitcoinAddress address, UnblindedSignature signature, int mixingLevel)>();
+ ActiveOutputs = Enumerable.Empty<ActiveOutput>();
}
public bool IsPhaseActionsComleted(CcjRoundPhase phase) => CompletedPhase >= phase;

MODIFY
WalletWasabi/Services/CcjClient.cs
WalletWasabi/Services/CcjClient.cs
@@ -340,7 +340,7 @@ namespace WalletWasabi.Services
{
TxOut[] myOutputs = unsignedCoinJoin.Outputs
.Where(x => x.ScriptPubKey == ongoingRound.Registration.ChangeAddress.ScriptPubKey
- || ongoingRound.Registration.ActiveOutputs.Select(y => y.address.ScriptPubKey).Contains(x.ScriptPubKey))
+ || ongoingRound.Registration.ActiveOutputs.Select(y => y.Address.ScriptPubKey).Contains(x.ScriptPubKey))
.ToArray();
Money amountBack = myOutputs.Sum(y => y.Value);
@@ -415,11 +415,11 @@ namespace WalletWasabi.Services
var shuffledOutputs = ongoingRound.Registration.ActiveOutputs.ToList();
shuffledOutputs.Shuffle();
- foreach ((BitcoinAddress address, UnblindedSignature signature, int mixingLevel) activeOutput in shuffledOutputs)
+ foreach (var activeOutput in shuffledOutputs)
{
using (var bobClient = new BobClient(CcjHostUriAction, TorSocks5EndPoint))
{
- if (!await bobClient.PostOutputAsync(ongoingRound.RoundId, activeOutput.address, activeOutput.signature, activeOutput.mixingLevel))
+ if (!await bobClient.PostOutputAsync(ongoingRound.RoundId, activeOutput))
{
Logger.LogWarning<AliceClient>($"Round ({ongoingRound.State.RoundId}) Bobs did not have enough time to post outputs before timeout. If you see this message, contact nopara73, so he can optimize the phase timeout periods to the worst Internet/Tor connections, which may be yours.)");
break;
@@ -430,7 +430,7 @@ namespace WalletWasabi.Services
{
if (ExposedLinks.ContainsKey(input)) // Should never not contain, but oh well, let's not disrupt the round for this.
{
- var found = ExposedLinks[input].FirstOrDefault(x => x.Key.GetP2wpkhAddress(Network) == activeOutput.address);
+ var found = ExposedLinks[input].FirstOrDefault(x => x.Key.GetP2wpkhAddress(Network) == activeOutput.Address);
if (found != default)
{
found.IsBlinded = false;
@@ -438,7 +438,7 @@ namespace WalletWasabi.Services
else
{
// Should never happen, but oh well we can autocorrect it so why not.
- ExposedLinks[input] = ExposedLinks[input].Append(new HdPubKeyBlindedPair(KeyManager.GetKeyForScriptPubKey(activeOutput.address.ScriptPubKey), false));
+ ExposedLinks[input] = ExposedLinks[input].Append(new HdPubKeyBlindedPair(KeyManager.GetKeyForScriptPubKey(activeOutput.Address.ScriptPubKey), false));
}
}
}

Create ActiveOutput class (instead of the touple we used previously.)