Пример #1
0
        /// <returns>If the phase is still in OutputRegistration.</returns>
        public async Task <bool> PostOutputAsync(long roundId, BitcoinAddress activeOutputAddress, UnblindedSignature unblindedSignature, int level)
        {
            Guard.MinimumAndNotNull(nameof(roundId), roundId, 0);
            Guard.NotNull(nameof(activeOutputAddress), activeOutputAddress);
            Guard.NotNull(nameof(unblindedSignature), unblindedSignature);
            Guard.MinimumAndNotNull(nameof(level), level, 0);

            var request = new OutputRequest {
                OutputAddress = activeOutputAddress, UnblindedSignature = unblindedSignature, Level = level
            };

            using (var response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{Constants.BackendMajorVersion}/btc/chaumiancoinjoin/output?roundId={roundId}", request.ToHttpStringContent()))
            {
                if (response.StatusCode == HttpStatusCode.Conflict)
                {
                    return(false);
                }
                else if (response.StatusCode != HttpStatusCode.NoContent)
                {
                    await response.ThrowRequestExceptionFromContentAsync();
                }

                return(true);
            }
        }
Пример #2
0
        public IOutputCreatedProcessState CreateProcess(OutputRequestDetails details,
                                                        IEnumerable <OutputCriteria> criterias,
                                                        String?boxNumber)
        {
            OutputRequest request = this.CreateRequest(details, criterias, boxNumber);

            return(new OutputCreatedProcessState(this, request));
        }
Пример #3
0
        public Task <IOutputCreatedProcessState> CreateProcessAsync(OutputRequestDetails details,
                                                                    IEnumerable <OutputCriteria> criterias,
                                                                    String?boxNumber,
                                                                    CancellationToken cancellationToken = default)
        {
            OutputRequest request = this.CreateRequest(details, criterias, boxNumber);

            return(Task.FromResult <IOutputCreatedProcessState>(new OutputCreatedProcessState(this, request)));
        }
Пример #4
0
 public virtual GetOutputResponse GetOutput(OutputRequest request)
 {
     return(new GetOutputResponse()
     {
         Status = ResponseStatus.Success,
         Output = OutputService.GetMemoryOutput(request?.FilterProcessorIds),
         DebugProcessors = CorePipelineService.GetDebugProcessors().Select(p => new SimpleProcessor(p)).ToList()
     });
 }
Пример #5
0
        public IActionResult OutputMovie(OutputRequest req)
        {
            if (!ServerData.ProjectList.ContainsKey(req.Uuid))
            {
                return(NotFound());
            }

            Movie.OutputMovie(Path.Combine(PileditSystem.AppLocation, "output"), req.Extention,
                              FourCC.FromString(req.FourCC), ServerData.ProjectList[req.Uuid]);
            return(Ok());
        }
Пример #6
0
        private void Dialog_RequestReceived(Object sender, MessageReceivedEventArgs <OutputRequest> e)
        {
            OutputRequest request = e.Message;

            this.OnMessageReceived(request,
                                   () =>
            {
                IOutputRequestedProcessState processState = new OutputRequestedProcessState(this, request);

                this.ProcessStarted?.Invoke(this, new ProcessStartedEventArgs <IOutputRequestedProcessState>(processState));
            });
        }
Пример #7
0
        public async Task PostOutputAsync(string roundHash, BitcoinAddress activeOutputAddress, byte[] unblindedSignature)
        {
            var request = new OutputRequest {
                OutputAddress = activeOutputAddress.ToString(), SignatureHex = ByteHelpers.ToHex(unblindedSignature)
            };

            using (var response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{Helpers.Constants.BackendMajorVersion}/btc/chaumiancoinjoin/output?roundHash={roundHash}", request.ToHttpStringContent()))
            {
                if (response.StatusCode != HttpStatusCode.NoContent)
                {
                    await response.ThrowRequestExceptionFromContentAsync();
                }
            }
        }
Пример #8
0
        public async Task PostOutputAsync(string roundHash, BitcoinAddress activeOutputAddress, byte[] unblindedSignature)
        {
            var request = new OutputRequest()
            {
                OutputAddress = activeOutputAddress.ToString(), SignatureHex = ByteHelpers.ToHex(unblindedSignature)
            };

            using (var response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v1/btc/chaumiancoinjoin/output?roundHash={roundHash}", request.ToHttpStringContent()))
            {
                if (response.StatusCode != HttpStatusCode.NoContent)
                {
                    string error = await response.Content.ReadAsJsonAsync <string>();

                    var errorMessage = error == null ? string.Empty : $"\n{error}";
                    throw new HttpRequestException($"{response.StatusCode.ToReasonString()}{errorMessage}");
                }
            }
        }
Пример #9
0
        public OutputStartedProcessState(OutputWorkflow workflow,
                                         OutputRequest request,
                                         Action <MessageReceivedEventArgs <OutputMessage> > outputProgressCallback)
        {
            this.Workflow = workflow;
            this.Request  = request;

            this.Interceptor = new MessageInterceptor <OutputMessage>(this.Workflow.Dialog,
                                                                      new MessageFilter(this.Request.Id),
                                                                      (MessageReceivedEventArgs <OutputMessage> e) =>
            {
                outputProgressCallback(e);
            });

            this.Response = this.Workflow.SendRequest(this.Request,
                                                      () =>
            {
                return(this.Workflow.Dialog.SendRequest(request));
            });
        }
Пример #10
0
        public async Task PostOutputAsync(OutputRequest request, CancellationToken cancel)
        {
            using (await _asyncLock.LockAsync())
            {
                string requestJsonString = JsonConvert.SerializeObject(request);
                var    content           = new StringContent(
                    requestJsonString,
                    Encoding.UTF8,
                    "application/json");

                HttpResponseMessage response = await PostAsync("output", content, cancel);

                if (!response.IsSuccessStatusCode)
                {
                    throw new HttpRequestException(response.StatusCode.ToString());
                }
                string responseString = await response.Content.ReadAsStringAsync();

                AssertSuccess(responseString);
            }
        }
Пример #11
0
        /// <returns>If the phase is still in OutputRegistration.</returns>
        public async Task <bool> PostOutputAsync(long roundId, ActiveOutput activeOutput)
        {
            Guard.MinimumAndNotNull(nameof(roundId), roundId, 0);
            Guard.NotNull(nameof(activeOutput), activeOutput);

            var request = new OutputRequest {
                OutputAddress = activeOutput.Address, UnblindedSignature = activeOutput.Signature, Level = activeOutput.MixingLevel
            };

            using var response = await TorClient.SendAsync(HttpMethod.Post, $"/api/v{WasabiClient.ApiVersion}/btc/chaumiancoinjoin/output?roundId={roundId}", request.ToHttpStringContent()).ConfigureAwait(false);

            if (response.StatusCode == HttpStatusCode.Conflict)
            {
                return(false);
            }
            else if (response.StatusCode != HttpStatusCode.NoContent)
            {
                await response.ThrowRequestExceptionFromContentAsync().ConfigureAwait(false);
            }

            return(true);
        }
Пример #12
0
 public Task <OutputResponse> SendRequestAsync(OutputRequest request, CancellationToken cancellationToken = default)
 {
     return(base.SendRequestAsync <OutputRequest, OutputResponse>(request, cancellationToken));
 }
Пример #13
0
 protected void OnRequestReceived(OutputRequest request)
 {
     this.RequestReceived?.Invoke(this, new MessageReceivedEventArgs <OutputRequest>(request, this.DialogProvider));
 }
        public async Task <IActionResult> PostOutputAsync([FromQuery, Required] long roundId, [FromBody, Required] OutputRequest request)
        {
            if (roundId < 0 ||
                request.Level < 0 ||
                !ModelState.IsValid)
            {
                return(BadRequest());
            }

            CoordinatorRound round = Coordinator.TryGetRound(roundId);

            if (round is null)
            {
                TryLogLateRequest(roundId, RoundPhase.OutputRegistration);
                return(NotFound("Round not found."));
            }

            if (round.Status != CoordinatorRoundStatus.Running)
            {
                TryLogLateRequest(roundId, RoundPhase.OutputRegistration);
                return(Gone("Round is not running."));
            }

            RoundPhase phase = round.Phase;

            if (phase != RoundPhase.OutputRegistration)
            {
                TryLogLateRequest(roundId, RoundPhase.OutputRegistration);
                return(Conflict($"Output registration can only be done from OutputRegistration phase. Current phase: {phase}."));
            }

            if (request.OutputAddress.Network != Network)
            {
                // RegTest and TestNet address formats are sometimes the same.
                if (Network == Network.Main)
                {
                    return(BadRequest($"Invalid OutputAddress Network."));
                }
            }

            if (request.OutputAddress == Constants.GetCoordinatorAddress(Network))
            {
                Logger.LogWarning($"Bob is registering the coordinator's address. Address: {request.OutputAddress}, Level: {request.Level}, Signature: {request.UnblindedSignature}.");
            }

            if (request.Level > round.MixingLevels.GetMaxLevel())
            {
                return(BadRequest($"Invalid mixing level is provided. Provided: {request.Level}. Maximum: {round.MixingLevels.GetMaxLevel()}."));
            }

            if (round.ContainsRegisteredUnblindedSignature(request.UnblindedSignature))
            {
                return(NoContent());
            }

            MixingLevel mixinglevel = round.MixingLevels.GetLevel(request.Level);
            Signer      signer      = mixinglevel.Signer;

            if (signer.VerifyUnblindedSignature(request.UnblindedSignature, request.OutputAddress.ScriptPubKey.ToBytes()))
            {
                using (await OutputLock.LockAsync())
                {
                    Bob bob = null;
                    try
                    {
                        bob = new Bob(request.OutputAddress, mixinglevel);
                        round.AddBob(bob);
                        round.AddRegisteredUnblindedSignature(request.UnblindedSignature);
                    }
                    catch (Exception ex)
                    {
                        return(BadRequest($"Invalid outputAddress is provided. Details: {ex.Message}"));
                    }

                    int bobCount      = round.CountBobs();
                    int blindSigCount = round.CountBlindSignatures();
                    if (bobCount == blindSigCount)                     // If there'll be more bobs, then round failed. Someone may broke the crypto.
                    {
                        await round.ExecuteNextPhaseAsync(RoundPhase.Signing);
                    }
                }

                return(NoContent());
            }
            return(BadRequest("Invalid signature provided."));
        }
Пример #15
0
 public OutputResponse SendRequest(OutputRequest request)
 {
     return(base.SendRequest <OutputRequest, OutputResponse>(request));
 }
Пример #16
0
 public OutputAbortingProcessState(OutputWorkflow workflow, OutputRequest request)
     :
     base(workflow, request)
 {
 }
Пример #17
0
 public OutputCreatedProcessState(OutputWorkflow workflow,
                                  OutputRequest request)
 {
     this.Workflow = workflow;
     this.Request  = request;
 }
        public async Task <IActionResult> PostOutputAsync([FromQuery] string roundHash, [FromBody] OutputRequest outputRequest)
        {
            if (string.IsNullOrWhiteSpace(roundHash) ||
                outputRequest == null ||
                string.IsNullOrWhiteSpace(outputRequest.OutputScript) ||
                string.IsNullOrWhiteSpace(outputRequest.SignatureHex) ||
                !ModelState.IsValid)
            {
                return(BadRequest());
            }

            CcjRound round = Coordinator.TryGetRound(roundHash);

            if (round == null)
            {
                return(NotFound("Round not found."));
            }

            if (round.Status != CcjRoundStatus.Running)
            {
                return(Forbid("Round is not running."));
            }

            CcjRoundPhase phase = round.Phase;

            if (phase != CcjRoundPhase.OutputRegistration)
            {
                return(Forbid($"Output registration can only be done from OutputRegistration phase. Current phase: {phase}."));
            }

            var outputScript = new Script(outputRequest.OutputScript);

            if (RsaKey.PubKey.Verify(ByteHelpers.FromHex(outputRequest.SignatureHex), outputScript.ToBytes()))
            {
                using (await OutputLock.LockAsync())
                {
                    Bob bob = null;
                    try
                    {
                        bob = new Bob(outputScript);
                        round.AddBob(bob);
                    }
                    catch (Exception ex)
                    {
                        return(BadRequest($"Invalid outputScript is provided. Details: {ex.Message}"));
                    }

                    if (round.CountBobs() == round.AnonymitySet)
                    {
                        await round.ExecuteNextPhaseAsync(CcjRoundPhase.Signing);
                    }
                }

                return(NoContent());
            }
            else
            {
                return(BadRequest("Invalid signature provided."));
            }
        }
Пример #19
0
 public OutputAcceptedProcessState(OutputWorkflow workflow, OutputRequest request)
     :
     base(workflow, request)
 {
 }
 protected AbortableOutputProcessState(OutputWorkflow workflow, OutputRequest request)
     :
     base(workflow, request)
 {
 }
Пример #21
0
 protected OutputProcessState(OutputWorkflow workflow, OutputRequest request)
 {
     this.Workflow = workflow;
     this.Request  = request;
 }
Пример #22
0
        public IActionResult Output([FromBody] OutputRequest request)
        {
            var          roundId = Global.StateMachine.RoundId;
            TumblerPhase phase   = TumblerPhase.OutputRegistration;

            try
            {
                if (Global.StateMachine.Phase != TumblerPhase.OutputRegistration || !Global.StateMachine.AcceptRequest)
                {
                    return(new ObjectResult(new FailureResponse {
                        Message = "Wrong phase"
                    }));
                }

                if (string.IsNullOrWhiteSpace(request.Output))
                {
                    return(new BadRequestResult());
                }
                if (string.IsNullOrWhiteSpace(request.Signature))
                {
                    return(new BadRequestResult());
                }
                if (string.IsNullOrWhiteSpace(request.RoundHash))
                {
                    return(new BadRequestResult());
                }

                if (request.RoundHash != Global.StateMachine.RoundHash)
                {
                    throw new ArgumentException("Wrong round hash provided");
                }

                var output = new BitcoinWitPubKeyAddress(request.Output, expectedNetwork: Global.Config.Network);
                // if not already registered
                if (Global.StateMachine.Bobs.Any(x => x.Output == output))
                {
                    return(new ObjectResult(new SuccessResponse()));
                }

                if (Global.RsaKey.PubKey.Verify(HexHelpers.GetBytes(request.Signature), Encoding.UTF8.GetBytes(request.Output)))
                {
                    try
                    {
                        AssertPhase(roundId, phase);

                        Global.StateMachine.Bobs.Add(new Bob {
                            Output = output
                        });

                        return(new ObjectResult(new SuccessResponse()));
                    }
                    finally
                    {
                        if (Global.StateMachine.Alices.Count == Global.StateMachine.Bobs.Count)
                        {
                            Global.StateMachine.UpdatePhase(TumblerPhase.Signing);
                        }
                    }
                }
                else
                {
                    throw new ArgumentException("Bad output");
                }
            }
            catch (Exception ex)
            {
                return(new ObjectResult(new FailureResponse {
                    Message = ex.Message
                }));
            }
        }