Use CredentialIssuer without two phased commit
MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PostRequests/ConfirmConnectionTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/PostRequests/ConfirmConnectionTests.cs
@@ -207,15 +207,11 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend.PostRequests
// invalidate serial numbers
issuer.HandleRequest(credentialsRequest);
- Assert.Equal(0, issuer2.Balance);
- Assert.Equal(credentialsRequest.Delta, issuer.Balance);
await using ArenaRequestHandler handler = new(cfg, new Prison(), arena, new MockRpcClient());
var ex = await Assert.ThrowsAsync<WabiSabiCryptoException>(async () => await handler.ConfirmConnectionAsync(req, CancellationToken.None));
Assert.Equal(WabiSabiCryptoErrorCode.SerialNumberAlreadyUsed, ex.ErrorCode);
Assert.False(alice.ConfirmedConnection);
- Assert.Equal(0, issuer2.Balance);
- Assert.Equal(credentialsRequest.Delta, issuer.Balance);
await arena.StopAsync(CancellationToken.None);
}
}

MODIFY
WalletWasabi/WabiSabi/Backend/Rounds/Arena.cs
WalletWasabi/WabiSabi/Backend/Rounds/Arena.cs
@@ -362,8 +362,8 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.TooMuchVsize);
}
- var amountCredentialTask = Task.Run(() => round.AmountCredentialIssuer.PrepareResponse(request.ZeroAmountCredentialRequests), cancellationToken);
- var vsizeCredentialTask = Task.Run(() => round.VsizeCredentialIssuer.PrepareResponse(request.ZeroVsizeCredentialRequests), cancellationToken);
+ var amountCredentialTask = round.AmountCredentialIssuer.HandleRequest(request.ZeroAmountCredentialRequests, cancellationToken);
+ var vsizeCredentialTask = round.VsizeCredentialIssuer.HandleRequest(request.ZeroVsizeCredentialRequests, cancellationToken);
if (round.RemainingInputVsizeAllocation < round.MaxVsizeAllocationPerAlice)
{
@@ -377,8 +377,8 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
round.Alices.Add(alice);
return new(alice.Id,
- commitAmountCredentialResponse.Commit(),
- commitVsizeCredentialResponse.Commit());
+ commitAmountCredentialResponse,
+ commitVsizeCredentialResponse);
}
}
@@ -475,15 +475,15 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
}
}
- var amountZeroTask = round.AmountCredentialIssuer.PrepareResponse(request.ZeroAmountCredentialRequests, cancellationToken);
- var vsizeZeroTask = round.VsizeCredentialIssuer.PrepareResponse(request.ZeroVsizeCredentialRequests, cancellationToken);
- Task<ICommitableCredentialsResponse>? amountRealTask = null;
- Task<ICommitableCredentialsResponse>? vsizeRealTask = null;
+ var amountZeroCredentialTask = round.AmountCredentialIssuer.HandleRequest(request.ZeroAmountCredentialRequests, cancellationToken);
+ var vsizeZeroCredentialTask = round.VsizeCredentialIssuer.HandleRequest(request.ZeroVsizeCredentialRequests, cancellationToken);
+ Task<CredentialsResponse>? amountRealCredentialTask = null;
+ Task<CredentialsResponse>? vsizeRealCredentialTask = null;
if (round.Phase is Phase.ConnectionConfirmation)
{
- amountRealTask = round.AmountCredentialIssuer.PrepareResponse(realAmountCredentialRequests, cancellationToken);
- vsizeRealTask = round.VsizeCredentialIssuer.PrepareResponse(realVsizeCredentialRequests, cancellationToken);
+ amountRealCredentialTask = round.AmountCredentialIssuer.HandleRequest(realAmountCredentialRequests, cancellationToken);
+ vsizeRealCredentialTask = round.VsizeCredentialIssuer.HandleRequest(realVsizeCredentialRequests, cancellationToken);
}
using (await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false))
@@ -497,34 +497,28 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
{
case Phase.InputRegistration:
{
- var commitAmountZeroCredentialResponse = await amountZeroTask.ConfigureAwait(false);
- var commitVsizeZeroCredentialResponse = await vsizeZeroTask.ConfigureAwait(false);
+ var commitAmountZeroCredentialResponse = await amountZeroCredentialTask.ConfigureAwait(false);
+ var commitVsizeZeroCredentialResponse = await vsizeZeroCredentialTask.ConfigureAwait(false);
alice.SetDeadlineRelativeTo(round.ConnectionConfirmationTimeout);
return new(
- commitAmountZeroCredentialResponse.Commit(),
- commitVsizeZeroCredentialResponse.Commit());
+ commitAmountZeroCredentialResponse,
+ commitVsizeZeroCredentialResponse);
}
case Phase.ConnectionConfirmation:
{
// If the phase was InputRegistration before then we did not pre-calculate real credentials.
- amountRealTask ??= round.AmountCredentialIssuer.PrepareResponse(realAmountCredentialRequests, cancellationToken);
- vsizeRealTask ??= round.VsizeCredentialIssuer.PrepareResponse(realVsizeCredentialRequests, cancellationToken);
+ amountRealCredentialTask ??= round.AmountCredentialIssuer.HandleRequest(realAmountCredentialRequests, cancellationToken);
+ vsizeRealCredentialTask ??= round.VsizeCredentialIssuer.HandleRequest(realVsizeCredentialRequests, cancellationToken);
- var commitAmountZeroCredentialResponse = await amountZeroTask.ConfigureAwait(false);
- var commitVsizeZeroCredentialResponse = await vsizeZeroTask.ConfigureAwait(false);
- var commitAmountRealCredentialResponse = await amountRealTask.ConfigureAwait(false);
- var commitVsizeRealCredentialResponse = await vsizeRealTask.ConfigureAwait(false);
+ ConnectionConfirmationResponse response = new(
+ await amountZeroCredentialTask.ConfigureAwait(false),
+ await vsizeZeroCredentialTask.ConfigureAwait(false),
+ await amountRealCredentialTask.ConfigureAwait(false),
+ await vsizeRealCredentialTask.ConfigureAwait(false));
// Update the CoinJoin state, adding the confirmed input.
round.CoinjoinState = round.Assert<ConstructionState>().AddInput(alice.Coin);
-
- ConnectionConfirmationResponse response = new(
- commitAmountZeroCredentialResponse.Commit(),
- commitVsizeZeroCredentialResponse.Commit(),
- commitAmountRealCredentialResponse.Commit(),
- commitVsizeRealCredentialResponse.Commit());
-
alice.ConfirmedConnection = true;
return response;
@@ -566,16 +560,12 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
var newState = round.AddOutput(new TxOut(outputValue, bob.Script));
// Verify the credential requests and prepare their responses.
- var commitAmountCredentialResponse = round.AmountCredentialIssuer.PrepareResponse(request.AmountCredentialRequests);
- var commitVsizeCredentialResponse = round.VsizeCredentialIssuer.PrepareResponse(vsizeCredentialRequests);
+ await round.AmountCredentialIssuer.HandleRequest(request.AmountCredentialRequests, cancellationToken).ConfigureAwait(false);
+ await round.VsizeCredentialIssuer.HandleRequest(vsizeCredentialRequests, cancellationToken).ConfigureAwait(false);
// Update round state.
round.Bobs.Add(bob);
round.CoinjoinState = newState;
-
- // Issue credentials and mark presented credentials as used.
- commitAmountCredentialResponse.Commit();
- commitVsizeCredentialResponse.Commit();
}
}
@@ -636,22 +626,16 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.WrongNumberOfCreds, $"Round ({round.Id}): Incorrect requested number of weight credentials.");
}
- var realAmountTask = round.AmountCredentialIssuer.PrepareResponse(request.RealAmountCredentialRequests, cancellationToken);
- var realVsizeTask = round.VsizeCredentialIssuer.PrepareResponse(request.RealVsizeCredentialRequests, cancellationToken);
- var zeroAmountTask = round.AmountCredentialIssuer.PrepareResponse(request.ZeroAmountCredentialRequests, cancellationToken);
- var zeroVsizeTask = round.VsizeCredentialIssuer.PrepareResponse(request.ZeroVsizeCredentialsRequests, cancellationToken);
-
- var commitRealAmountCredentialResponse = await realAmountTask.ConfigureAwait(false);
- var commitRealVsizeCredentialResponse = await realVsizeTask.ConfigureAwait(false);
- var commitZeroAmountCredentialResponse = await zeroAmountTask.ConfigureAwait(false);
- var commitZeroVsizeCredentialResponse = await zeroVsizeTask.ConfigureAwait(false);
+ var realAmountTask = round.AmountCredentialIssuer.HandleRequest(request.RealAmountCredentialRequests, cancellationToken);
+ var realVsizeTask = round.VsizeCredentialIssuer.HandleRequest(request.RealVsizeCredentialRequests, cancellationToken);
+ var zeroAmountTask = round.AmountCredentialIssuer.HandleRequest(request.ZeroAmountCredentialRequests, cancellationToken);
+ var zeroVsizeTask = round.VsizeCredentialIssuer.HandleRequest(request.ZeroVsizeCredentialsRequests, cancellationToken);
return new(
- commitRealAmountCredentialResponse.Commit(),
- commitRealVsizeCredentialResponse.Commit(),
- commitZeroAmountCredentialResponse.Commit(),
- commitZeroVsizeCredentialResponse.Commit()
- );
+ await realAmountTask.ConfigureAwait(false),
+ await realVsizeTask.ConfigureAwait(false),
+ await zeroAmountTask.ConfigureAwait(false),
+ await zeroVsizeTask.ConfigureAwait(false));
}
public async Task<Coin> OutpointToCoinAsync(InputRegistrationRequest request, CancellationToken cancellationToken)

MODIFY
WalletWasabi/WabiSabi/Crypto/CredentialIssuer.cs
WalletWasabi/WabiSabi/Crypto/CredentialIssuer.cs
@@ -102,6 +102,9 @@ namespace WalletWasabi.WabiSabi.Crypto
public CredentialsResponse HandleRequest(CredentialsRequest registrationRequest)
=> PrepareResponse(registrationRequest).Commit();
+ public Task<CredentialsResponse> HandleRequest(CredentialsRequest registrationRequest, CancellationToken cancel)
+ => Task.Run(() => HandleRequest(registrationRequest), cancel);
+
/// <summary>
/// Validate the <see cref="CredentialsRequest">credentials registration requests</see> and
/// prepare to mark the serial numbers as used and issue the credentials.

Use CredentialIssuer without two phased commit