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 } });
            }
        }
Example #2
0
        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();
        }
Example #3
0
        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);
        }
Example #4
0
        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;
            }
        }
Example #5
0
        //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());
            }
        }