public async Task <EmptyResponse> RegisterOutputCoreAsync(OutputRegistrationRequest request, CancellationToken cancellationToken) { using (await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false)) { var round = GetRound(request.RoundId, Phase.OutputRegistration); var credentialAmount = -request.AmountCredentialRequests.Delta; Bob bob = new(request.Script, credentialAmount); var outputValue = bob.CalculateOutputAmount(round.FeeRate); var vsizeCredentialRequests = request.VsizeCredentialRequests; if (-vsizeCredentialRequests.Delta != bob.OutputVsize) { throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.IncorrectRequestedVsizeCredentials, $"Round ({request.RoundId}): Incorrect requested vsize credentials."); } // Update the current round state with the additional output to ensure it's valid. var newState = round.AddOutput(new TxOut(outputValue, bob.Script)); // Verify the credential requests and prepare their responses. await round.AmountCredentialIssuer.HandleRequestAsync(request.AmountCredentialRequests, cancellationToken).ConfigureAwait(false); await round.VsizeCredentialIssuer.HandleRequestAsync(vsizeCredentialRequests, cancellationToken).ConfigureAwait(false); // Update round state. round.Bobs.Add(bob); round.CoinjoinState = newState; } return(EmptyResponse.Instance); }
public async Task <EmptyResponse> RegisterOutputCoreAsync(OutputRegistrationRequest request, CancellationToken cancellationToken) { using (await AsyncLock.LockAsync(cancellationToken).ConfigureAwait(false)) { var round = GetRound(request.RoundId, Phase.OutputRegistration); var credentialAmount = -request.AmountCredentialRequests.Delta; if (CoinJoinScriptStore?.Contains(request.Script) is true) { Logger.LogWarning($"Round ({request.RoundId}): Already registered script."); throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.AlreadyRegisteredScript, $"Round ({request.RoundId}): Already registered script."); } var inputScripts = round.Alices.Select(a => a.Coin.ScriptPubKey).ToHashSet(); if (inputScripts.Contains(request.Script)) { Logger.LogWarning($"Round ({request.RoundId}): Already registered script in the round."); throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.AlreadyRegisteredScript, $"Round ({request.RoundId}): Already registered script in round."); } Bob bob = new(request.Script, credentialAmount); var outputValue = bob.CalculateOutputAmount(round.Parameters.MiningFeeRate); var vsizeCredentialRequests = request.VsizeCredentialRequests; if (-vsizeCredentialRequests.Delta != bob.OutputVsize) { throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.IncorrectRequestedVsizeCredentials, $"Round ({request.RoundId}): Incorrect requested vsize credentials."); } // Update the current round state with the additional output to ensure it's valid. var newState = round.AddOutput(new TxOut(outputValue, bob.Script)); // Verify the credential requests and prepare their responses. await round.AmountCredentialIssuer.HandleRequestAsync(request.AmountCredentialRequests, cancellationToken).ConfigureAwait(false); await round.VsizeCredentialIssuer.HandleRequestAsync(vsizeCredentialRequests, cancellationToken).ConfigureAwait(false); // Update round state. round.Bobs.Add(bob); round.CoinjoinState = newState; } return(EmptyResponse.Instance); }
public async Task RegisterOutputAsync(OutputRegistrationRequest request, CancellationToken cancellationToken) { await IdempotencyRequestCache.GetCachedResponseAsync(request, action : (request, token) => Arena.RegisterOutputCoreAsync(request, token), cancellationToken); }
public Task <OutputRegistrationResponse> RegisterOutputAsync(OutputRegistrationRequest request, CancellationToken cancellableToken) { return(RequestHandler.RegisterOutputAsync(request, cancellableToken)); }
public Task RegisterOutputAsync(OutputRegistrationRequest request, CancellationToken cancellationToken) => SendAndReceiveAsync <OutputRegistrationRequest>(RemoteAction.RegisterOutput, request, cancellationToken);
public Task RegisterOutputAsync(OutputRegistrationRequest request, CancellationToken cancellationToken) { return(RegisterOutputCoreAsync(request, cancellationToken)); }
public Task <OutputRegistrationResponse> RegisterOutputAsync(OutputRegistrationRequest request, CancellationToken cancellationToken) => arena.RegisterOutputAsync(request);