Esempio n. 1
0
        private static void MoveFromPoisonToProcessing()
        {
            try
            {
                Console.WriteLine("Are you sure?: Y/N");
                var input = Console.ReadLine();
                if (input.ToLower() != "y")
                {
                    Console.WriteLine("Cancel");
                    return;
                }
                Console.WriteLine("Started");

                var queueFactory = ServiceProvider.GetService <IQueueFactory>();
                var queuePoison  = queueFactory.Build(Constants.PendingOperationsQueue + "-poison");
                var queue        = queueFactory.Build(Constants.PendingOperationsQueue);
                var count        = queuePoison.Count().Result;
                for (int i = 0; i < count; i++)
                {
                    var message = queuePoison.GetRawMessageAsync().Result;

                    OperationHashMatchMessage newMessage = JsonConvert.DeserializeObject <OperationHashMatchMessage>(message.AsString);

                    queue.PutRawMessageAsync(message.AsString).Wait();
                    queuePoison.FinishRawMessageAsync(message);
                }

                Console.WriteLine("All Processed");
            }
            catch (Exception e)
            {
            }
        }
Esempio n. 2
0
        public async Task MonitoringOperationJobUnitTest_SkipIfNoBalance()
        {
            string operationId = Guid.NewGuid().ToString();
            OperationHashMatchMessage message = new OperationHashMatchMessage()
            {
                OperationId     = operationId,
                PutDateTime     = DateTime.UtcNow,
                TransactionHash = null
            };

            #region Arrange Mocks
            IPendingOperation pendingOperation = new PendingOperation()
            {
                Amount             = "1000000000000000000",
                FromAddress        = "fromAddress",
                OperationId        = operationId,
                OperationType      = OperationTypes.Transfer,
                ToAddress          = "toAddress",
                CoinAdapterAddress = "coinAdapter",
            };

            _pendingOperationService.Setup(x => x.GetOperationAsync(pendingOperation.OperationId)).Returns(Task.FromResult(pendingOperation));
            _transferContractService.Setup(x => x.GetBalanceOnAdapter(pendingOperation.CoinAdapterAddress, pendingOperation.FromAddress, true))
            .Returns(Task.FromResult(new BigInteger(0)));
            _coinEventService.Setup(x => x.PublishEvent(It.IsAny <ICoinEvent>(), It.IsAny <bool>())).Returns(Task.FromResult(0)).Verifiable();

            #endregion

            MonitoringOperationJob job = GetJob();
            await job.Execute(message, new Lykke.JobTriggers.Triggers.Bindings.QueueTriggeringContext(DateTimeOffset.UtcNow));

            _coinEventService.Verify(x => x.PublishEvent(It.IsAny <ICoinEvent>(), It.IsAny <bool>()), Times.Never);
        }
Esempio n. 3
0
        private static void MoveToPendingOperationQueue(string fromQueue)
        {
            var queueFactory = ServiceProvider.GetService <IQueueFactory>();
            var queuePoison  = queueFactory.Build(fromQueue);
            var queue        = queueFactory.Build(Constants.PendingOperationsQueue);
            var count        = queuePoison.Count().Result;

            for (int i = 0; i < count; i++)
            {
                var message = queuePoison.GetRawMessageAsync().Result;

                OperationHashMatchMessage newMessage = JsonConvert.DeserializeObject <OperationHashMatchMessage>(message.AsString);
                newMessage.DequeueCount = 0;
                queue.PutRawMessageAsync(message.AsString).Wait();
                queuePoison.FinishRawMessageAsync(message).Wait();
            }
        }
        public async Task RemoveFromPendingOperationQueue(string opId)
        {
            var count = await _queue.Count();

            for (int i = 0; i < count; i++)
            {
                var message = await _queue.GetRawMessageAsync();

                OperationHashMatchMessage newMessage = JsonConvert.DeserializeObject <OperationHashMatchMessage>(message.AsString);

                await _queue.FinishRawMessageAsync(message);

                if (newMessage.OperationId?.ToLower() != opId?.ToLower())
                {
                    await _queue.PutRawMessageAsync(message.AsString);
                }
            }
        }
Esempio n. 5
0
        public async Task ProcessOperation(OperationHashMatchMessage opMessage, QueueTriggeringContext context,
                                           Func <Guid, string, string, string, BigInteger, string, Task <string> > transferDelegate)
        {
            try
            {
                var operation = await _pendingOperationService.GetOperationAsync(opMessage.OperationId);

                if (operation == null)
                {
                    await _coinEventResubmittQueue.PutRawMessageAsync(JsonConvert.SerializeObject(opMessage));

                    return;
                }

                if (_hotWalletAddress == operation.FromAddress.ToLower() &&
                    opMessage.DequeueCount == 0)
                {
                    opMessage.DequeueCount++;
                    context.MoveMessageToEnd(opMessage.ToJson());
                    context.SetCountQueueBasedDelay(_settings.MaxQueueDelay, 200);

                    return;
                }

                var guid   = Guid.Parse(operation.OperationId);
                var amount = BigInteger.Parse(operation.Amount);

                BigInteger    resultAmount;
                string        transactionHash = null;
                CoinEventType?eventType       = null;
                BigInteger    currentBalance  = await _transferContractService.GetBalanceOnAdapter(
                    operation.CoinAdapterAddress,
                    operation.FromAddress,
                    checkInPendingBlock : true);

                switch (operation.OperationType)
                {
                case OperationTypes.Cashout:
                    eventType    = CoinEventType.CashoutStarted;
                    resultAmount = amount;
                    if (!CheckBalance(currentBalance, resultAmount))
                    {
                        break;
                    }
                    transactionHash = await _exchangeContractService.CashOut(guid,
                                                                             operation.CoinAdapterAddress,
                                                                             operation.FromAddress,
                                                                             operation.ToAddress, amount, operation.SignFrom);

                    break;

                case OperationTypes.Transfer:
                    eventType    = CoinEventType.TransferStarted;
                    resultAmount = amount;
                    if (!CheckBalance(currentBalance, resultAmount))
                    {
                        break;
                    }
                    transactionHash = await transferDelegate(guid, operation.CoinAdapterAddress,
                                                             operation.FromAddress,
                                                             operation.ToAddress, amount, operation.SignFrom);

                    break;

                case OperationTypes.TransferWithChange:
                    eventType = CoinEventType.TransferStarted;
                    BigInteger change = BigInteger.Parse(operation.Change);
                    resultAmount = amount - change;
                    if (!CheckBalance(currentBalance, resultAmount))
                    {
                        break;
                    }
                    transactionHash = await _exchangeContractService.TransferWithChange(guid, operation.CoinAdapterAddress,
                                                                                        operation.FromAddress,
                                                                                        operation.ToAddress, amount, operation.SignFrom, change, operation.SignTo);

                    break;

                default:
                    await _log.WriteWarningAsync("MonitoringOperationJob", "Execute", $"Can't find right operation type for {opMessage.OperationId}", "");

                    break;
                }

                if (transactionHash != null && eventType != null)
                {
                    await _pendingOperationService.MatchHashToOpId(transactionHash, operation.OperationId);

                    await _coinEventService.PublishEvent(new CoinEvent(operation.OperationId.ToString(), transactionHash, operation.FromAddress, operation.ToAddress, resultAmount.ToString(), eventType.Value, operation.CoinAdapterAddress));

                    await _eventTraceRepository.InsertAsync(new EventTrace()
                    {
                        Note        = $"Operation Processed. Put it in the {Constants.TransactionMonitoringQueue}. With hash {transactionHash}",
                        OperationId = operation.OperationId,
                        TraceDate   = DateTime.UtcNow
                    });

                    return;
                }
            }
            catch (ClientSideException clientSideExc) when(clientSideExc.ExceptionType == ExceptionType.OperationWithIdAlreadyExists)
            {
                await _coinEventResubmittQueue.PutRawMessageAsync(JsonConvert.SerializeObject(opMessage));

                return;
            }
            catch (RpcClientException exc)
            {
                await _log.WriteErrorAsync("MonitoringOperationJob", "Execute", "RpcException", exc);

                opMessage.LastError = exc.Message;
                opMessage.DequeueCount++;
                if (opMessage.DequeueCount < 6)
                {
                    context.MoveMessageToEnd(opMessage.ToJson());
                    context.SetCountQueueBasedDelay(_settings.MaxQueueDelay, 200);
                }
                else
                {
                    context.MoveMessageToPoison(opMessage.ToJson());
                }

                return;
            }
            catch (Exception ex)
            {
                if (ex.Message != opMessage.LastError)
                {
                    await _log.WriteWarningAsync("MonitoringOperationJob", "Execute", $"OperationId: [{opMessage.OperationId}]", "");
                }

                opMessage.LastError = ex.Message;
                opMessage.DequeueCount++;
                context.MoveMessageToPoison(opMessage.ToJson());

                await _log.WriteErrorAsync("MonitoringOperationJob", "Execute", "", ex);

                return;
            }

            opMessage.DequeueCount++;
            context.MoveMessageToEnd(opMessage.ToJson());
            context.SetCountQueueBasedDelay(_settings.MaxQueueDelay, 200);
        }
Esempio n. 6
0
 public async Task Execute(OperationHashMatchMessage opMessage, QueueTriggeringContext context)
 {
     await ProcessOperation(opMessage, context, _exchangeContractService.Transfer);
 }
        public async Task Execute(OperationHashMatchMessage opMessage, QueueTriggeringContext context)
        {
            try
            {
                string operatioId = opMessage.OperationId;
                IOperationResubmitt opResubmitCounter = await _operationResubmittRepository.GetAsync(operatioId);

                if (opResubmitCounter == null)
                {
                    opResubmitCounter = new OperationResubmitt()
                    {
                        OperationId    = operatioId,
                        ResubmittCount = 0
                    };
                }
                if (opResubmitCounter.ResubmittCount > 2)
                {
                    await _log.WriteWarningAsync("CoinEventResubmittJob", "Execute", "", $"Message put to poison {opMessage.OperationId}");

                    context.MoveMessageToPoison(opMessage.ToJson());

                    return;
                }

                var historicalMessages = await _pendingOperationService.GetHistoricalAsync(opMessage.OperationId);

                if (historicalMessages == null || historicalMessages.Count() == 0)
                {
                    //Process cashin operations
                    var coinEvent = await _coinEventService.GetCoinEventById(opMessage.OperationId);

                    if (coinEvent != null &&
                        await _ethereumTransactionService.IsTransactionExecuted(coinEvent.TransactionHash, Constants.GasForCoinTransaction))
                    {
                        await ResubmittTransactionAsync(coinEvent.TransactionHash, operatioId, opResubmitCounter);

                        return;
                    }
                    else
                    {
                        context.MoveMessageToPoison(opMessage.ToJson());
                        await _slackNotifier.ErrorAsync($"Moved message {opMessage.OperationId} to poison: no corresponding coinEvent");
                    }
                }
                else
                {
                    //Process transfer/cashout operations
                    foreach (var match in historicalMessages)
                    {
                        if (!string.IsNullOrEmpty(match.TransactionHash) &&
                            await _ethereumTransactionService.IsTransactionExecuted(match.TransactionHash, Constants.GasForCoinTransaction))
                        {
                            var coinEvent = await _coinEventService.GetCoinEventById(match.OperationId);

                            if (coinEvent != null && coinEvent.TransactionHash.ToLower() == match.TransactionHash.ToLower())
                            {
                                await ResubmittTransactionAsync(match.TransactionHash, operatioId, opResubmitCounter);

                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (opMessage.DequeueCount > 100000)
                {
                    context.MoveMessageToPoison(opMessage.ToJson());
                    await _slackNotifier.ErrorAsync($"Moved message {opMessage.OperationId} to poison: dequeue count is {opMessage.DequeueCount }" +
                                                    $" error is {ex.Message}");

                    return;
                }
                opMessage.LastError = ex.Message;
                opMessage.DequeueCount++;
                context.MoveMessageToEnd(opMessage.ToJson());

                await _log.WriteErrorAsync("MonitoringOperationJob", "Execute", "", ex);

                return;
            }

            if (opMessage.DequeueCount > 100000)
            {
                context.MoveMessageToPoison(opMessage.ToJson());
                await _slackNotifier.ErrorAsync($"Moved message {opMessage.OperationId} to poison: dequeue count is {opMessage.DequeueCount }");
            }
            else
            {
                opMessage.DequeueCount++;
                context.MoveMessageToEnd(opMessage.ToJson());
            }
        }
Esempio n. 8
0
 private void MoveMessageToQueueEnd(OperationHashMatchMessage opMessage, QueueTriggeringContext context)
 {
     opMessage.DequeueCount++;
     context.MoveMessageToEnd(opMessage.ToJson());
     context.SetCountQueueBasedDelay(_settings.MaxQueueDelay, 200);
 }