private async Task CheckUnconfirmedTransaction(IUnconfirmedTransaction unconfirmedTransaction)
        {
            var operationMeta = await _operationMetaRepository.GetAsync(unconfirmedTransaction.OperationId);

            if (operationMeta == null)
            {
                _log.Warning(unconfirmedTransaction.ToJson(), "OperationMeta not found");

                return;
            }

            var confirmationCount = await _blockChainProvider.GetTxConfirmationCountAsync(unconfirmedTransaction.TxHash);

            var isCompleted = confirmationCount >= _confirmationsSettings.MinConfirmationsToDetectOperation;

            ;
            if (isCompleted)
            {
                //Force update balances
                var fromAddressUpdatedBalance = await operationMeta.Inputs.SelectAsync(async o => await _walletBalanceService.UpdateBtcBalanceAsync(o.Address,
                                                                                                                                                    _confirmationsSettings.MinConfirmationsToDetectOperation))
                ;

                var toAddressUpdatedBalance = await operationMeta.Outputs.SelectAsync(async o =>
                                                                                      await _walletBalanceService.UpdateBtcBalanceAsync(o.Address,
                                                                                                                                        _confirmationsSettings.MinConfirmationsToDetectOperation));


                var operationCompletedLoggingContext = new
                {
                    unconfirmedTransaction.OperationId,
                    unconfirmedTransaction.TxHash,
                    fromAddressUpdatedBalance,
                    toAddressUpdatedBalance
                };

                await _operationEventRepository.InsertIfNotExistAsync(OperationEvent.Create(
                                                                          unconfirmedTransaction.OperationId,
                                                                          OperationEventType.DetectedOnBlockChain, operationCompletedLoggingContext));

                _log.Info(operationCompletedLoggingContext.ToJson(), "Operation completed");


                await _unconfirmedTransactionRepository.DeleteIfExistAsync(unconfirmedTransaction.OperationId);
            }

            var status = isCompleted
                ? BroadcastStatus.Completed
                : BroadcastStatus.InProgress;

            var lastBlockHeight = await _blockChainProvider.GetLastBlockHeightAsync();

            await _observableOperationRepository.InsertOrReplaceAsync(ObervableOperation.Create(operationMeta, status,
                                                                                                unconfirmedTransaction.TxHash,
                                                                                                lastBlockHeight));
        }
Exemplo n.º 2
0
 public static UnconfirmedTransactionEntity Create(IUnconfirmedTransaction source)
 {
     return(new UnconfirmedTransactionEntity
     {
         PartitionKey = GeneratePartitionKey(source.OperationId),
         RowKey = GenerateRowKey(),
         OperationId = source.OperationId,
         TxHash = source.TxHash
     });
 }
Exemplo n.º 3
0
        private async Task CheckTransaction(IUnconfirmedTransaction unconfirmedTx)
        {
            var operation = await _operationRepository.GetOrDefault(unconfirmedTx.OperationId);

            if (operation == null)
            {
                _log.Error(nameof(DetectTransactionsPeriodicalHandler),
                           message: $"Aggregate for operation {unconfirmedTx.OperationId} not found");

                return;
            }

            var blockchainTx = await _blockchainProvider.GetTransactionOrDefaultAsync(unconfirmedTx.TxHash);

            var isCompleted = blockchainTx?.blockHash != null; //once a tx included in a block means the tx is confirmed by the 7 consensus nodes and cannt be reversed

            var lastBlockHeight = await _blockchainProvider.GetHeightAsync();

            var status = isCompleted
                ? BroadcastStatus.Completed
                : BroadcastStatus.InProgress;

            await _observableOperationRepository.InsertOrReplace(ObervableOperation.Create(operation, status,
                                                                                           unconfirmedTx.TxHash,
                                                                                           lastBlockHeight));

            if (isCompleted)
            {
                var fromAddressBalance = await _walletBalanceService.UpdateBalance(operation.FromAddress);

                var toAddressBalance = await _walletBalanceService.UpdateBalance(operation.ToAddress);

                var operationCompletedLoggingContext = new
                {
                    unconfirmedTx.OperationId,
                    unconfirmedTx.TxHash,
                    fromAddressBalance,
                    toAddressBalance
                };

                _log.Info("Transaction detected on blockchain", context: operationCompletedLoggingContext);


                await _unconfirmedTransactionRepository.DeleteIfExist(unconfirmedTx.OperationId);

                operation.OnDetectedOnBlockcain(DateTime.UtcNow);
                await _operationRepository.Save(operation);
            }
        }
Exemplo n.º 4
0
 public Task InsertOrReplace(IUnconfirmedTransaction tx)
 {
     return(_storage.InsertOrReplaceAsync(UnconfirmedTransactionEntity.Create(tx)));
 }