コード例 #1
0
        private async Task CheckDuplicatedTransactionId(Guid?transactionId)
        {
            if (!transactionId.HasValue)
            {
                return;
            }

            var data = await _signRequestRepository.GetSignRequest(transactionId.Value);

            if (data != null)
            {
                throw new BackendException("Transaction with same id already exists", ErrorCode.DuplicateTransactionId);
            }
        }
コード例 #2
0
        public async Task Broadcast([FromBody] BroadcastTransactionRequest model)
        {
            var signRequest = await _transactionSignRequestRepository.GetSignRequest(model.TransactionId);

            if (signRequest == null)
            {
                throw new BackendException("Transaction is not found", ErrorCode.BadTransaction);
            }

            if (signRequest.Invalidated == true)
            {
                throw new BackendException("Transaction was invalidated", ErrorCode.BadTransaction);
            }

            var initialTransaction = await _transactionBlobStorage.GetTransaction(model.TransactionId, TransactionBlobType.Initial);

            if (!TransactionComparer.CompareTransactions(initialTransaction, model.Transaction))
            {
                throw new BackendException("Signed transaction is not equals to initial transaction", ErrorCode.BadTransaction);
            }

            var transaction = new Transaction(model.Transaction);

            if (transaction.Inputs.All(o => o.ScriptSig == null || o.ScriptSig.Length == 0))
            {
                throw new BackendException("Transaction is not signed by client", ErrorCode.BadTransaction);
            }

            var fullSignedHex = signRequest.DoNotSign ? model.Transaction : await _signatureApiProvider.SignTransaction(model.Transaction);

            await _transactionBlobStorage.AddOrReplaceTransaction(model.TransactionId, TransactionBlobType.Signed, fullSignedHex);

            var fullSigned = new Transaction(fullSignedHex);

            await _broadcastService.BroadcastTransaction(model.TransactionId, fullSigned, useHandlers : false, savePaidFees : !signRequest.DoNotSign);
        }
コード例 #3
0
        public async Task ProcessMessage(TransactionQueueMessage message, QueueTriggeringContext context)
        {
            CreateTransactionResponse transactionResponse;

            try
            {
                var request = await _signRequestRepository.GetSignRequest(message.TransactionId);

                if (request?.Invalidated == true)
                {
                    context.MoveMessageToPoison(message.ToJson());
                    return;
                }

                switch (message.Type)
                {
                case TransactionCommandType.Issue:
                    var issue = message.Command.DeserializeJson <IssueCommand>();
                    transactionResponse = await _lykkeTransactionBuilderService.GetIssueTransaction(
                        OpenAssetsHelper.ParseAddress(issue.Address),
                        issue.Amount, await _assetRepository.GetAssetById(issue.Asset), message.TransactionId);

                    break;

                case TransactionCommandType.Transfer:
                    var transfer = message.Command.DeserializeJson <TransferCommand>();
                    transactionResponse = await _lykkeTransactionBuilderService.GetTransferTransaction(
                        OpenAssetsHelper.ParseAddress(transfer.SourceAddress),
                        OpenAssetsHelper.ParseAddress(transfer.DestinationAddress), transfer.Amount,
                        await _assetRepository.GetAssetById(transfer.Asset), message.TransactionId);

                    break;

                case TransactionCommandType.TransferAll:
                    var transferAll = message.Command.DeserializeJson <TransferAllCommand>();
                    transactionResponse = await _lykkeTransactionBuilderService.GetTransferAllTransaction(
                        OpenAssetsHelper.ParseAddress(transferAll.SourceAddress),
                        OpenAssetsHelper.ParseAddress(transferAll.DestinationAddress),
                        message.TransactionId);

                    break;

                case TransactionCommandType.Swap:
                    var swap = message.Command.DeserializeJson <SwapCommand>();
                    transactionResponse = await _lykkeTransactionBuilderService.GetSwapTransaction(
                        OpenAssetsHelper.ParseAddress(swap.MultisigCustomer1),
                        swap.Amount1,
                        await _assetRepository.GetAssetById(swap.Asset1),
                        OpenAssetsHelper.ParseAddress(swap.MultisigCustomer2),
                        swap.Amount2,
                        await _assetRepository.GetAssetById(swap.Asset2),
                        message.TransactionId);

                    break;

                case TransactionCommandType.Destroy:
                    var destroy = message.Command.DeserializeJson <DestroyCommand>();
                    transactionResponse = await _lykkeTransactionBuilderService.GetDestroyTransaction(
                        OpenAssetsHelper.ParseAddress(destroy.Address),
                        destroy.Amount,
                        await _assetRepository.GetAssetById(destroy.Asset),
                        message.TransactionId);

                    break;

                case TransactionCommandType.SegwitTransferToHotwallet:
                    var segwitTransfer = message.Command.DeserializeJson <SegwitTransferCommand>();
                    transactionResponse = await _lykkeTransactionBuilderService.GetTransferFromSegwitWallet(
                        OpenAssetsHelper.ParseAddress(segwitTransfer.SourceAddress), message.TransactionId);

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            catch (BackendException e) when(e.Code == ErrorCode.NoCoinsFound)
            {
                if (message.Type == TransactionCommandType.SegwitTransferToHotwallet)
                {
                    _cqrsEngine.PublishEvent(new CashinCompletedEvent {
                        OperationId = message.TransactionId
                    }, BitcoinBoundedContext.Name);
                }
                return;
            }
            catch (BackendException e)
            {
                if (e.Text != message.LastError)
                {
                    await _logger.WriteWarningAsync("TransactionBuildFunction", "ProcessMessage", $"Id: [{message.TransactionId}], cmd: [{message.Command}]", e.Text);
                }

                message.LastError = e.Text;
                if (message.DequeueCount >= _settings.MaxDequeueCount)
                {
                    context.MoveMessageToPoison(message.ToJson());
                }
                else
                {
                    message.DequeueCount++;
                    context.MoveMessageToEnd(message.ToJson());
                    context.SetCountQueueBasedDelay(_settings.MaxQueueDelay, 200);
                }
                return;
            }

            await _transactionBlobStorage.AddOrReplaceTransaction(message.TransactionId, TransactionBlobType.Initial, transactionResponse.Transaction);


            await _queueFactory(Constants.BroadcastingQueue).PutRawMessageAsync(new BroadcastingTransaction
            {
                TransactionCommandType = message.Type,
                TransactionId          = message.TransactionId
            }.ToJson());
        }