public async Task <CommandHandlingResult> Handle(ProcessEthCoinEventCommand command, IEventPublisher eventPublisher) { var sw = new Stopwatch(); sw.Start(); try { switch (command.CoinEventType) { case CoinEventType.CashinCompleted: await ProcessCashIn(command, eventPublisher); break; case CoinEventType.TransferCompleted: case CoinEventType.CashoutCompleted: await ProcessOutcomeOperation(command); break; case CoinEventType.CashoutFailed: await ProcessFailedCashout(command); break; case CoinEventType.CashinStarted: case CoinEventType.CashoutStarted: case CoinEventType.TransferStarted: //DO NOTHING! break; default: throw new ArgumentOutOfRangeException( $"{command.CoinEventType} - is not supported for processing {command.ToJson()}. "); } return(CommandHandlingResult.Ok()); } catch (Exception e) { _log.Error(nameof(ProcessEthCoinEventCommand), e, context: command); throw; } finally { sw.Stop(); _log.Info("Command execution time", context: new { TxHandler = new { Handler = nameof(EthereumCoreCommandHandler), Command = nameof(ProcessEthCoinEventCommand), Time = sw.ElapsedMilliseconds } }); } }
private async Task ProcessOutcomeOperation(ProcessEthCoinEventCommand queueMessage) { var transferTx = await _ethereumTransactionRequestRepository.GetAsync(Guid.Parse(queueMessage.OperationId)); CashOutContextData context = await _transactionService.GetTransactionContext <CashOutContextData>(queueMessage.OperationId); if (transferTx != null) { switch (transferTx.OperationType) { case OperationType.CashOut: await SetCashoutHashes(transferTx, queueMessage.TransactionHash); break; case OperationType.Trade: await SetTradeHashes(transferTx, queueMessage.TransactionHash); break; case OperationType.TransferToTrusted: case OperationType.TransferFromTrusted: await SetTransferHashes(transferTx, queueMessage.TransactionHash); break; } ChaosKitty.Meow(); return; } if (context == null) { return; } string clientId = context.ClientId; string hash = queueMessage.TransactionHash; string cashOperationId = context.CashOperationId; var clientAcc = await _clientAccountClient.GetByIdAsync(clientId); var clientEmail = await _personalDataService.GetEmailAsync(clientId); await _cashOperationsRepositoryClient.UpdateBlockchainHashAsync(clientId, cashOperationId, hash); await _srvEmailsFacade.SendNoRefundOCashOutMail(clientAcc.PartnerId, clientEmail, context.Amount, context.AssetId, hash); ChaosKitty.Meow(); }
private async Task ProcessCashIn(ProcessEthCoinEventCommand queueMessage, IEventPublisher eventPublisher) { if (queueMessage.CoinEventType != CoinEventType.CashinCompleted) { return; } var bcnCreds = await _bcnClientCredentialsRepository.GetByAssetAddressAsync(queueMessage.FromAddress); var asset = await _assetsServiceWithCache.TryGetAssetAsync(bcnCreds.AssetId); var amount = EthServiceHelpers.ConvertFromContract(queueMessage.Amount, asset.MultiplierPower, asset.Accuracy); Guid.TryParse(bcnCreds.ClientId, out var clientId); await HandleCashInOperation(asset, amount, clientId, bcnCreds.Address, queueMessage.TransactionHash, eventPublisher, createPendingActions : true); }
public async Task <CommandHandlingResult> Handle(ProcessEthCoinEventCommand command, IEventPublisher eventPublisher) { try { switch (command.CoinEventType) { case CoinEventType.CashinCompleted: await ProcessCashIn(command, eventPublisher); break; case CoinEventType.TransferCompleted: case CoinEventType.CashoutCompleted: await ProcessOutcomeOperation(command); break; case CoinEventType.CashoutFailed: await ProcessFailedCashout(command); break; case CoinEventType.CashinStarted: case CoinEventType.CashoutStarted: case CoinEventType.TransferStarted: //DO NOTHING! break; default: throw new ArgumentOutOfRangeException($"{command.CoinEventType} - is not supported for processing {command.ToJson()}. "); } return(CommandHandlingResult.Ok()); } catch (Exception e) { _log.Error(nameof(ProcessEthCoinEventCommand), e, context: command); throw; } }
//TODO: Split wth the help of the process management private async Task ProcessFailedCashout(ProcessEthCoinEventCommand queueMessage) { CashOutContextData context = await _transactionService.GetTransactionContext <CashOutContextData>(queueMessage.OperationId); if (context != null) { string transactionHandlerUserId = "auto redeem"; string clientId = context.ClientId; string hash = queueMessage.TransactionHash; string cashOperationId = context.CashOperationId; string assetId = context.AssetId; var amount = context.Amount; try { ChaosKitty.Meow(); var asset = await _assetsService.AssetGetAsync(assetId); await _cashOperationsRepositoryClient.UpdateBlockchainHashAsync(clientId, cashOperationId, hash); var pt = await _paymentTransactionsRepository.TryCreateAsync(PaymentTransaction.Create(hash, CashInPaymentSystem.Ethereum, clientId, (double)amount, asset.DisplayId ?? asset.Id, status: PaymentStatus.Processing)); if (pt == null) { _log.Warning($"{nameof(EthereumCoreCommandHandler)}:{nameof(ProcessFailedCashout)}", "Transaction already handled", context: hash); return; //if was handled previously } ChaosKitty.Meow(); var sign = "+"; var commentText = $"Balance Update: {sign}{amount} {asset.Name}. Cashout failed: {hash} {queueMessage.OperationId}"; var newComment = new ClientComment { ClientId = clientId, Comment = commentText, CreatedAt = DateTime.UtcNow, FullName = "Lykke.Job.TransactionHandler", UserId = transactionHandlerUserId }; var exResult = await _exchangeOperationsServiceClient.ExchangeOperations.ManualCashInAsync( new ManualCashInRequestModel { ClientId = clientId, AssetId = assetId, Amount = (double)amount, UserId = "auto redeem", Comment = commentText, }); if (!exResult.IsOk()) { _log.Warning($"{nameof(EthereumCoreCommandHandler)}:{nameof(ProcessFailedCashout)}", "ME operation failed", context: new { ExchangeServiceResponse = exResult, QueueMessage = queueMessage }.ToJson()); } await _clientCommentsRepository.AddClientCommentAsync(newComment); await _paymentTransactionsRepository.SetStatus(hash, PaymentStatus.NotifyProcessed); ChaosKitty.Meow(); } catch (Exception e) { _log.Error($"{nameof(EthereumCoreCommandHandler)}:{nameof(ProcessFailedCashout)}", e, context: queueMessage.ToJson()); throw; } } else { _log.Warning("Can't get a context", context: queueMessage.ToJson()); } }