Refactor CloneExcept code smell
MODIFY
WalletWasabi.Tests/ModelTests.cs
WalletWasabi.Tests/ModelTests.cs
@@ -12,8 +12,10 @@ using WalletWasabi.Backend.Models.Requests;
using WalletWasabi.Backend.Models.Responses;
using WalletWasabi.JsonConverters;
using WalletWasabi.Models;
+using WalletWasabi.Models.ChaumianCoinJoin;
using WalletWasabi.Services;
using WalletWasabi.Tests.XunitConfiguration;
+using WalletWasabi.WebClients.Wasabi.ChaumianCoinJoin;
using Xunit;
namespace WalletWasabi.Tests

MODIFY
WalletWasabi.Tests/RegTests.cs
WalletWasabi.Tests/RegTests.cs
@@ -1827,6 +1827,17 @@ namespace WalletWasabi.Tests
coordinator.AbortAllRoundsInInputRegistration(nameof(RegTests), "");
using (var aliceClient = await AliceClient.CreateNewAsync(network, inputsRequest, baseUri))
{
+ // Test DelayedClientRoundRegistration logic.
+ ClientRoundRegistration first = null;
+ var second = new ClientRoundRegistration(aliceClient,
+ new[] { new SmartCoin(uint256.One, 1, Script.Empty, Money.Zero, new[] { new TxoRef(uint256.One, 1) }, Height.Unknown, true, 1) },
+ new List<(BitcoinAddress, BlindSignature, int)> { (BitcoinAddress.Create("12Rty3c8j3QiZSwLVaBtch6XUMZaja3RC7", Network.Main), null, 1) },
+ BitcoinAddress.Create("12Rty3c8j3QiZSwLVaBtch6XUMZaja3RC7", Network.Main));
+ first = second;
+ second = null;
+ Assert.NotNull(first);
+ Assert.Null(second);
+
Assert.NotNull(aliceClient.BlindedOutputSignatures);
Assert.NotEqual(Guid.Empty, aliceClient.UniqueId);
Assert.True(aliceClient.RoundId > 0);

MODIFY
WalletWasabi/Backend/Models/Responses/CcjRunningRoundState.cs
WalletWasabi/Backend/Models/Responses/CcjRunningRoundState.cs
@@ -41,25 +41,6 @@ namespace WalletWasabi.Backend.Models.Responses
/// </summary>
public int SuccessfulRoundCount { get; set; }
- public static CcjRunningRoundState CloneExcept(CcjRunningRoundState state, long roundId, int registeredPeerCount)
- {
- return new CcjRunningRoundState
- {
- Phase = state.Phase,
- Denomination = state.Denomination,
- SchnorrPubKeys = state.SchnorrPubKeys,
- RegisteredPeerCount = registeredPeerCount,
- RequiredPeerCount = state.RequiredPeerCount,
- CoordinatorFeePercent = state.CoordinatorFeePercent,
- FeePerInputs = state.FeePerInputs,
- FeePerOutputs = state.FeePerOutputs,
- MaximumInputCountPerPeer = state.MaximumInputCountPerPeer,
- RegistrationTimeout = state.RegistrationTimeout,
- RoundId = roundId,
- SuccessfulRoundCount = state.SuccessfulRoundCount
- };
- }
-
public Money CalculateRequiredAmount(params Money[] queuedCoinAmounts)
{
var tried = new List<Money>();

MODIFY
WalletWasabi/Services/CcjClient.cs
WalletWasabi/Services/CcjClient.cs
@@ -28,6 +28,8 @@ namespace WalletWasabi.Services
public Network Network { get; }
public KeyManager KeyManager { get; }
+ private ClientRoundRegistration DelayedRoundRegistration { get; set; }
+
public Uri CcjHostUri { get; }
public WasabiSynchronizer Synchronizer { get; }
private IPEndPoint TorSocks5EndPoint { get; }
@@ -79,6 +81,7 @@ namespace WalletWasabi.Services
State = new CcjClientState();
MixLock = new AsyncLock();
_statusProcessing = 0;
+ DelayedRoundRegistration = null;
Synchronizer.ResponseArrived += Synchronizer_ResponseArrivedAsync;
}
@@ -177,6 +180,14 @@ namespace WalletWasabi.Services
Interlocked.Exchange(ref _statusProcessing, 1);
using (await MixLock.LockAsync())
{
+ // First, if there's delayed round registration update based on the state.
+ if (DelayedRoundRegistration != null)
+ {
+ CcjClientRound roundRegistered = State.GetSingleOrDefaultRound(DelayedRoundRegistration.AliceClient.RoundId);
+ roundRegistered.Registration = DelayedRoundRegistration;
+ DelayedRoundRegistration = null; // Don't dispose.
+ }
+
await DequeueCoinsFromMixNoLockAsync(State.GetSpentCoins().ToArray());
State.UpdateRoundsByStates(states.ToArray());
@@ -631,10 +642,9 @@ namespace WalletWasabi.Services
CcjClientRound roundRegistered = State.GetSingleOrDefaultRound(aliceClient.RoundId);
if (roundRegistered is null)
{
- // If our SatoshiClient doesn't yet know about the round because of the dealy, create it.
- // Make its state as it'd be the same as our assumed round was, except the roundId and registeredPeerCount, it'll be updated later.
- roundRegistered = new CcjClientRound(CcjRunningRoundState.CloneExcept(inputRegistrableRound.State, aliceClient.RoundId, registeredPeerCount: 1));
- State.AddOrReplaceRound(roundRegistered);
+ // If our SatoshiClient doesn't yet know about the round, because of delay, then delay the round registration.
+ DelayedRoundRegistration?.Dispose();
+ DelayedRoundRegistration = registration;
}
roundRegistered.Registration = registration;

Refactor CloneExcept code smell