public async Task BroadCastTransactionAsync(Guid operationId, Transaction tx)
        {
            var operation = await _operationMetaRepository.GetAsync(operationId);

            if (operation == null)
            {
                throw new BusinessException("Operation not found", ErrorCode.BadInputParameter);
            }

            if (await _operationEventRepository.ExistAsync(operationId, OperationEventType.Broadcasted))
            {
                throw new BusinessException("Transaction already brodcasted", ErrorCode.TransactionAlreadyBroadcasted);
            }
            var hash = tx.GetHash().ToString();
            await _transactionBlobStorage.AddOrReplaceTransactionAsync(operationId, hash,
                                                                       TransactionBlobType.BeforeBroadcast, tx.ToHex());

            var lastBlockHeight = await _blockChainProvider.GetLastBlockHeightAsync();

            await _blockChainProvider.BroadCastTransactionAsync(tx);

            await _observableOperationRepository.InsertOrReplaceAsync(ObervableOperation.Create(operation,
                                                                                                BroadcastStatus.InProgress, hash, lastBlockHeight));

            await _unconfirmedTransactionRepository.InsertOrReplaceAsync(
                UnconfirmedTransaction.Create(operationId, hash));

            await _transactionOutputsService.CompleteTxOutputs(operationId, tx);

            await _operationEventRepository.InsertIfNotExistAsync(OperationEvent.Create(operationId,
                                                                                        OperationEventType.Broadcasted));
        }
Exemple #2
0
        public async Task <BuiltTransactionInfo> GetOrBuildTransferTransactionAsync(Guid operationId,
                                                                                    IList <OperationInput> inputs,
                                                                                    IList <OperationOutput> outputs,
                                                                                    OperationType operationType,
                                                                                    string assetId,
                                                                                    bool includeFee)
        {
            var existingOperation = await _operationMetaRepository.GetAsync(operationId);

            if (existingOperation != null)
            {
                if (!OperationMetaComparer.Compare(existingOperation, inputs, outputs, assetId, includeFee))
                {
                    throw new BusinessException("Conflict in operation parameters", ErrorCode.Conflict);
                }
                return(await GetExistingTransaction(existingOperation.OperationId, existingOperation.Hash));
            }
            IBuiltTransaction builtTransaction;

            switch (operationType)
            {
            case OperationType.Single:
                builtTransaction = await _transactionBuilder.GetTransferTransactionAsync(inputs.Single(), outputs.Single(), includeFee);

                break;

            case OperationType.ManyInputs:
                builtTransaction = await _transactionBuilder.GetManyInputsTransferTransactionAsync(inputs, outputs.Single(), includeFee);

                break;

            case OperationType.ManyOutputs:
                builtTransaction = await _transactionBuilder.GetManyOutputsTransferTransactionAsync(inputs.Single(), outputs, includeFee);

                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(operationType));
            }

            var builtTransactionInfo = new BuiltTransactionInfo
            {
                TransactionHex = builtTransaction.TransactionData.ToHex(),
                UsedCoins      = builtTransaction.UsedCoins
            };

            await _transactionOutputsService.AddInternalOutputs(operationId,
                                                                builtTransaction.TransactionData.Outputs.AsCoins());

            var txHash = builtTransaction.TransactionData.GetHash().ToString();

            await _transactionBlobStorage.AddOrReplaceTransactionAsync(operationId, txHash, TransactionBlobType.Initial,
                                                                       builtTransactionInfo.ToJson(_network));

            var operation = OperationMeta.Create(operationId, txHash, inputs, outputs, assetId, builtTransaction.Fee.Satoshi, includeFee);

            if (await _operationMetaRepository.TryInsertAsync(operation))
            {
                return(builtTransactionInfo);
            }

            existingOperation = await _operationMetaRepository.GetAsync(operationId);

            return(await GetExistingTransaction(operationId, existingOperation.Hash));
        }