public async Task <InputRegistrationResponse> RegisterInputAsync(InputRegistrationRequest request, CancellationToken cancellationToken) { try { return(await RegisterInputCoreAsync(request, cancellationToken).ConfigureAwait(false)); } catch (Exception ex) when(IsUserCheating(ex)) { Prison.Ban(request.Input, request.RoundId); throw; } }
public async Task <ConnectionConfirmationResponse> ConfirmConnectionAsync(ConnectionConfirmationRequest request, CancellationToken cancellationToken) { try { return(await ConfirmConnectionCoreAsync(request, cancellationToken).ConfigureAwait(false)); } catch (Exception ex) when(IsUserCheating(ex)) { var round = GetRound(request.RoundId); var alice = GetAlice(request.AliceId, round); Prison.Ban(alice.Coin.Outpoint, round.Id); throw; } }
public async Task <ConnectionConfirmationResponse> ConfirmConnectionAsync(ConnectionConfirmationRequest request, CancellationToken cancellationToken) { Round round; Alice alice; var realAmountCredentialRequests = request.RealAmountCredentialRequests; var realVsizeCredentialRequests = request.RealVsizeCredentialRequests; using (await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false)) { round = GetRound(request.RoundId, Phase.InputRegistration, Phase.ConnectionConfirmation); alice = GetAlice(request.AliceId, round); if (alice.ConfirmedConnection) { Prison.Ban(alice, round.Id); throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.AliceAlreadyConfirmedConnection, $"Round ({request.RoundId}): Alice ({request.AliceId}) already confirmed connection."); } if (realVsizeCredentialRequests.Delta != alice.CalculateRemainingVsizeCredentials(round.MaxVsizeAllocationPerAlice)) { throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.IncorrectRequestedVsizeCredentials, $"Round ({request.RoundId}): Incorrect requested vsize credentials."); } if (realAmountCredentialRequests.Delta != alice.CalculateRemainingAmountCredentials(round.FeeRate)) { throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.IncorrectRequestedAmountCredentials, $"Round ({request.RoundId}): Incorrect requested amount credentials."); } } var amountZeroCredentialTask = round.AmountCredentialIssuer.HandleRequestAsync(request.ZeroAmountCredentialRequests, cancellationToken); var vsizeZeroCredentialTask = round.VsizeCredentialIssuer.HandleRequestAsync(request.ZeroVsizeCredentialRequests, cancellationToken); Task <CredentialsResponse>?amountRealCredentialTask = null; Task <CredentialsResponse>?vsizeRealCredentialTask = null; if (round.Phase is Phase.ConnectionConfirmation) { amountRealCredentialTask = round.AmountCredentialIssuer.HandleRequestAsync(realAmountCredentialRequests, cancellationToken); vsizeRealCredentialTask = round.VsizeCredentialIssuer.HandleRequestAsync(realVsizeCredentialRequests, cancellationToken); } using (await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false)) { alice = GetAlice(request.AliceId, round); switch (round.Phase) { case Phase.InputRegistration: { var commitAmountZeroCredentialResponse = await amountZeroCredentialTask.ConfigureAwait(false); var commitVsizeZeroCredentialResponse = await vsizeZeroCredentialTask.ConfigureAwait(false); alice.SetDeadlineRelativeTo(round.ConnectionConfirmationTimeFrame.Duration); return(new( commitAmountZeroCredentialResponse, commitVsizeZeroCredentialResponse)); } case Phase.ConnectionConfirmation: { // If the phase was InputRegistration before then we did not pre-calculate real credentials. amountRealCredentialTask ??= round.AmountCredentialIssuer.HandleRequestAsync(realAmountCredentialRequests, cancellationToken); vsizeRealCredentialTask ??= round.VsizeCredentialIssuer.HandleRequestAsync(realVsizeCredentialRequests, cancellationToken); 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); alice.ConfirmedConnection = true; return(response); } default: throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.WrongPhase, $"Round ({request.RoundId}): Wrong phase ({round.Phase})."); } } }