public async Task BroadCastTransaction(Guid operationId, Transaction tx) { var operation = await _operationMetaRepository.Get(operationId); if (operation == null) { throw new BusinessException("Operation not found", ErrorCode.BadInputParameter); } if (await _operationEventRepository.Exist(operationId, OperationEventType.Broadcasted)) { throw new BusinessException("Transaction already brodcasted", ErrorCode.TransactionAlreadyBroadcasted); } var hash = tx.GetHash().ToString(); await _transactionBlobStorage.AddOrReplaceTransaction(operationId, hash, TransactionBlobType.BeforeBroadcast, tx.ToHex()); var lastBlockHeight = await _blockChainProvider.GetLastBlockHeight(); await _blockChainProvider.BroadCastTransaction(tx); await _observableOperationRepository.InsertOrReplace(ObervableOperation.Create(operation, BroadcastStatus.InProgress, hash, lastBlockHeight)); await _unconfirmedTransactionRepository.InsertOrReplace(UnconfirmedTransaction.Create(operationId, hash)); await _operationEventRepository.InsertIfNotExist(OperationEvent.Create(operationId, OperationEventType.Broadcasted)); await _spentOutputRepository.InsertSpentOutputs(operationId, tx.Inputs.Select(i => new Output(i.PrevOut))); }
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)); }
public async Task DetectUnconfirmedTransactions() { var unconfirmedTxs = await _unconfirmedTransactionRepository.GetAll(); foreach (var unconfirmedTransaction in unconfirmedTxs) { var operationMeta = await _operationMetaRepository.Get(unconfirmedTransaction.OperationId); if (operationMeta == null) { await _log.WriteWarningAsync(nameof(UpdateObservableOperations), nameof(DetectUnconfirmedTransactions), unconfirmedTransaction.ToJson(), "OperationMeta not found"); continue; } var confirmationCount = await _blockChainProvider.GetTxConfirmationCount(unconfirmedTransaction.TxHash); var isCompleted = confirmationCount >= _confirmationsSettings.MinConfirmationsToDetectOperation; ; if (isCompleted) { //Force update balances var fromAddressUpdatedBalance = await _walletBalanceService.UpdateBalance(operationMeta.FromAddress); var toAddressUpdatedBalance = await _walletBalanceService.UpdateBalance(operationMeta.ToAddress); var operationCompletedLoggingContext = new { unconfirmedTransaction.OperationId, unconfirmedTransaction.TxHash, fromAddressUpdatedBalance, toAddressUpdatedBalance }; await _operationEventRepository.InsertIfNotExist(OperationEvent.Create(unconfirmedTransaction.OperationId, OperationEventType.DetectedOnBlockChain, operationCompletedLoggingContext)); await _log.WriteInfoAsync(nameof(UpdateBalanceFunctions), nameof(DetectUnconfirmedTransactions), operationCompletedLoggingContext.ToJson(), "Operation completed"); await _unconfirmedTransactionRepository.DeleteIfExist(unconfirmedTransaction.OperationId); } var status = isCompleted ? BroadcastStatus.Completed : BroadcastStatus.InProgress; await _observableOperationRepository.InsertOrReplace(ObervableOperation.Create(operationMeta, status, unconfirmedTransaction.TxHash)); } }