private async Task ProcessIssue(CashInOutQueueMessage message) { var isClientTrusted = await _clientAccountClient.IsTrustedAsync(message.ClientId); var asset = await _assetsServiceWithCache.TryGetAssetAsync(message.AssetId); if (!isClientTrusted.Value && !asset.IsTrusted) { _log.Warning($"{nameof(CashInOutMessageProcessor)}:{nameof(ProcessIssue)}", "Client and asset are not trusted.", context: message.ToJson()); return; } var walletCredentials = await _walletCredentialsRepository.GetAsync(message.ClientId); var amount = message.Amount.ParseAnyDecimal(); var transactionId = message.Id; var context = await _transactionService.GetTransactionContext <IssueContextData>(transactionId); context.CashOperationId = transactionId; _cqrsEngine.SendCommand(new SaveIssueOperationStateCommand { Command = new IssueCommand { TransactionId = Guid.Parse(transactionId), Context = context.ToJson(), Amount = Math.Abs(amount), AssetId = message.AssetId, Multisig = walletCredentials?.MultiSig }, Context = context, Message = message }, BoundedContexts.TxHandler, BoundedContexts.Operations); }
public async Task <CommandHandlingResult> Handle(ProcessLimitOrderCommand command, IEventPublisher eventPublisher) { var clientId = command.LimitOrder.Order.ClientId; if (!_trusted.ContainsKey(clientId)) { _trusted[clientId] = (await _clientAccountClient.IsTrustedAsync(clientId)).Value; } var isTrustedClient = _trusted[clientId]; var limitOrderExecutedEvent = new LimitOrderExecutedEvent { IsTrustedClient = isTrustedClient, LimitOrder = command.LimitOrder }; var tradesWerePerformed = command.LimitOrder.Trades != null && command.LimitOrder.Trades.Any(); if (!isTrustedClient) { // need previous order state for not trusted clients var prevOrderState = await _limitOrdersRepository.GetOrderAsync(command.LimitOrder.Order.ClientId, command.LimitOrder.Order.Id); var isImmediateTrade = tradesWerePerformed && command.LimitOrder.Trades.First().Timestamp == command.LimitOrder.Order.Registered; limitOrderExecutedEvent.HasPrevOrderState = prevOrderState != null && !isImmediateTrade; limitOrderExecutedEvent.PrevRemainingVolume = prevOrderState?.RemainingVolume; limitOrderExecutedEvent.Aggregated = AggregateSwaps(limitOrderExecutedEvent.LimitOrder.Trades); } await _limitOrdersRepository.CreateOrUpdateAsync(command.LimitOrder.Order); var status = (OrderStatus)Enum.Parse(typeof(OrderStatus), command.LimitOrder.Order.Status); // workaround: ME sends wrong status if (status == OrderStatus.Processing && !tradesWerePerformed) { status = OrderStatus.InOrderBook; } else if (status == OrderStatus.PartiallyMatched && !tradesWerePerformed) { status = OrderStatus.Placed; } if (status == OrderStatus.Processing || status == OrderStatus.PartiallyMatched || // new version of Processing status == OrderStatus.Matched || status == OrderStatus.Cancelled) { limitOrderExecutedEvent.Trades = await CreateTrades(command.LimitOrder); } eventPublisher.PublishEvent(limitOrderExecutedEvent); return(CommandHandlingResult.Ok()); }
public async Task <SwapOffchainContextData> FillTradeContext(SwapOffchainContextData context, TradeQueueItem.MarketOrder order, List <TradeQueueItem.TradeInfo> trades, string clientId) { context.Order = order; context.Trades = trades; context.ClientTrades = await _clientTradesFactory.Create(order, trades, clientId); context.IsTrustedClient = (await _clientAccountClient.IsTrustedAsync(clientId)).Value; context.Status = OperationStatus.Matched; if (!context.IsTrustedClient) { var aggregatedTrades = await AggregateSwaps(trades); context.SellTransfer = aggregatedTrades.sellTransfer; context.BuyTransfer = aggregatedTrades.buyTransfer; var operations = new[] { aggregatedTrades.sellTransfer, aggregatedTrades.buyTransfer }; foreach (var operation in operations) { var trade = context.ClientTrades.FirstOrDefault(x => x.ClientId == clientId && x.AssetId == operation.Asset.Id && Math.Abs(x.Amount - (double)operation.Amount) < LykkeConstants.Eps); // find existed operation (which was inserted in LW after guarantee transfer) var existed = context.Operations.FirstOrDefault(x => x.ClientId == clientId && x.AssetId == operation.Asset.Id); if (existed != null) { existed.ClientTradeId = trade?.Id; continue; } context.Operations.Add(new SwapOffchainContextData.Operation() { TransactionId = operation.TransferId, Amount = operation.Amount, ClientId = clientId, AssetId = operation.Asset.Id, ClientTradeId = trade?.Id }); } } return(context); }
public async Task <CommandHandlingResult> Handle(ProcessLimitOrderCommand command, IEventPublisher eventPublisher) { var sw = new Stopwatch(); sw.Start(); var stepWatch = new Stopwatch(); stepWatch.Start(); try { var clientId = command.LimitOrder.Order.ClientId; if (!_trusted.ContainsKey(clientId)) { _trusted[clientId] = (await _clientAccountClient.IsTrustedAsync(clientId)).Value; } _log.Info("LimitOrderProcessing", new { TxHandler = new { Step = "01. Check client account is trusted", Time = stepWatch.ElapsedMilliseconds } }); stepWatch.Restart(); var isTrustedClient = _trusted[clientId]; var limitOrderExecutedEvent = new LimitOrderExecutedEvent { IsTrustedClient = isTrustedClient, LimitOrder = command.LimitOrder }; var tradesWerePerformed = command.LimitOrder.Trades != null && command.LimitOrder.Trades.Any(); if (!isTrustedClient) { // need previous order state for not trusted clients var prevOrderState = await _limitOrdersRepository.GetOrderAsync(command.LimitOrder.Order.ClientId, command.LimitOrder.Order.Id); var isImmediateTrade = tradesWerePerformed && command.LimitOrder.Trades.First().Timestamp == command.LimitOrder.Order.Registered; limitOrderExecutedEvent.HasPrevOrderState = prevOrderState != null && !isImmediateTrade; limitOrderExecutedEvent.PrevRemainingVolume = prevOrderState?.RemainingVolume; limitOrderExecutedEvent.Aggregated = AggregateSwaps(limitOrderExecutedEvent.LimitOrder.Trades); _log.Info("LimitOrderProcessing", new { TxHandler = new { Step = "02. Get Previous order state for not trusted client", Time = stepWatch.ElapsedMilliseconds } }); stepWatch.Restart(); } if (!isTrustedClient) { await _limitOrdersRepository.CreateOrUpdateAsync(command.LimitOrder.Order); _log.Info("LimitOrderProcessing", new { TxHandler = new { Step = "03. Upsert limit order for not trusted client", Time = stepWatch.ElapsedMilliseconds } }); stepWatch.Restart(); } var status = (OrderStatus)Enum.Parse(typeof(OrderStatus), command.LimitOrder.Order.Status); // workaround: ME sends wrong status if (status == OrderStatus.Processing && !tradesWerePerformed) { status = OrderStatus.InOrderBook; } else if (status == OrderStatus.PartiallyMatched && !tradesWerePerformed) { status = OrderStatus.Placed; } if (status == OrderStatus.Processing || status == OrderStatus.PartiallyMatched || // new version of Processing status == OrderStatus.Matched || status == OrderStatus.Cancelled) { limitOrderExecutedEvent.Trades = await CreateTrades(command.LimitOrder); } _log.Info("LimitOrderProcessing", new { TxHandler = new { Step = "04. Create trades", Time = stepWatch.ElapsedMilliseconds } }); stepWatch.Restart(); eventPublisher.PublishEvent(limitOrderExecutedEvent); return(CommandHandlingResult.Ok()); } finally { sw.Stop(); _log.Info("Command execution time", context: new { TxHandler = new { Handler = nameof(LimitOrderCommandHandler), Command = nameof(ProcessLimitOrderCommand), Time = sw.ElapsedMilliseconds } }); } }