public async Task Insert_Transaction_Test()
        {
            var transaction = _kernelTestHelper.GenerateTransaction();
            var hash        = await _transactionManager.AddTransactionAsync(transaction);

            hash.ShouldNotBeNull();
        }
Exemple #2
0
 public async Task TestInsert()
 {
     await _manager.AddTransactionAsync(new Transaction
     {
         From = Address.FromRawBytes(Hash.Generate().ToByteArray()),
         To   = Address.FromRawBytes(Hash.Generate().ToByteArray())
     });
 }
 public async Task AddTransactionsAsync(IEnumerable <Transaction> transactions)
 {
     foreach (var transaction in transactions)
     {
         await _transactionManager.AddTransactionAsync(transaction);
     }
 }
Exemple #4
0
 public async Task HandleTransactionsReceivedAsync(TransactionsReceivedEvent eventData)
 {
     foreach (var transaction in eventData.Transactions)
     {
         _allTransactions.Add(transaction.GetHash(), transaction);
         await _transactionManager.AddTransactionAsync(transaction);
     }
 }
Exemple #5
0
        private async Task ProcessTransactionAsync(QueuedTransaction queuedTransaction)
        {
            if (_allTransactions.Count > _transactionOptions.PoolLimit)
            {
                return;
            }

            if (_allTransactions.ContainsKey(queuedTransaction.TransactionId))
            {
                return;
            }

            if (!queuedTransaction.Transaction.VerifyExpiration(_bestChainHeight))
            {
                return;
            }

            var validationResult =
                await _transactionValidationService.ValidateTransactionAsync(queuedTransaction.Transaction);

            if (!validationResult)
            {
                return;
            }

            var hasTransaction = await _blockchainService.HasTransactionAsync(queuedTransaction.TransactionId);

            if (hasTransaction)
            {
                return;
            }

            await _transactionManager.AddTransactionAsync(queuedTransaction.Transaction);

            var addSuccess = _allTransactions.TryAdd(queuedTransaction.TransactionId, queuedTransaction);

            if (!addSuccess)
            {
                return;
            }

            var prefix = await GetPrefixByHeightAsync(queuedTransaction.Transaction.RefBlockNumber, _bestChainHash);

            UpdateRefBlockStatus(queuedTransaction, prefix, _bestChainHeight);

            if (queuedTransaction.RefBlockStatus == RefBlockStatus.RefBlockExpired)
            {
                return;
            }

            if (queuedTransaction.RefBlockStatus == RefBlockStatus.RefBlockValid)
            {
                await LocalEventBus.PublishAsync(new TransactionAcceptedEvent()
                {
                    Transaction = queuedTransaction.Transaction
                });
            }
        }
Exemple #6
0
        public async Task AddBlockAsync(Block block)
        {
            await _blockManager.AddBlockHeaderAsync(block.Header);

            foreach (var transaction in block.Body.TransactionList)
            {
                await _transactionManager.AddTransactionAsync(transaction);
            }

            await _blockManager.AddBlockBodyAsync(block.Header.GetHash(), block.Body);
        }
Exemple #7
0
 public async Task HandleTransactionsReceivedAsync(TransactionsReceivedEvent eventData)
 {
     foreach (var transaction in eventData.Transactions)
     {
         if (_allTransactions.ContainsKey(transaction.GetHash()))
         {
             continue;
         }
         _allTransactions.Add(transaction.GetHash(), transaction);
         await _transactionManager.AddTransactionAsync(transaction);
     }
 }
Exemple #8
0
        private async Task <QueuedTransaction> AcceptTransactionAsync(QueuedTransaction queuedTransaction)
        {
            if (!await VerifyTransactionAcceptableAsync(queuedTransaction))
            {
                return(null);
            }

            var validationResult =
                await _transactionValidationService.ValidateTransactionWhileCollectingAsync(new ChainContext
            {
                BlockHash   = _bestChainHash,
                BlockHeight = _bestChainHeight
            }, queuedTransaction.Transaction);

            if (!validationResult)
            {
                Logger.LogDebug($"Transaction {queuedTransaction.TransactionId} validation failed.");
                return(null);
            }

            // double check
            var hasTransaction = await _blockchainService.HasTransactionAsync(queuedTransaction.TransactionId);

            if (hasTransaction)
            {
                return(null);
            }

            await _transactionManager.AddTransactionAsync(queuedTransaction.Transaction);

            var addSuccess = _allTransactions.TryAdd(queuedTransaction.TransactionId, queuedTransaction);

            if (addSuccess)
            {
                await UpdateQueuedTransactionRefBlockStatusAsync(queuedTransaction);

                return(queuedTransaction);
            }

            Logger.LogWarning($"Transaction {queuedTransaction.TransactionId} insert failed.");
            return(null);
        }
Exemple #9
0
        /// <summary>
        /// Update database
        /// </summary>
        /// <param name="executedTxs"></param>
        /// <param name="txResults"></param>
        /// <param name="block"></param>
        private async Task <HashSet <Address> > InsertTxs(IEnumerable <Transaction> executedTxs,
                                                          IEnumerable <TransactionResult> txResults, IBlock block)
        {
            var bn      = block.Header.Index;
            var bh      = block.Header.GetHash();
            var address = new HashSet <Address>();

            foreach (var t in executedTxs)
            {
                address.Add(t.From);
                await _transactionManager.AddTransactionAsync(t);
            }

            txResults.AsParallel().ForEach(async r =>
            {
                r.BlockNumber = bn;
                r.BlockHash   = bh;
                await _transactionResultManager.AddTransactionResultAsync(r);
            });
            return(address);
        }
Exemple #10
0
        // Change transaction status and add transaction into TransactionManager.
        private void UpdateExecutedTransactions(IEnumerable <Hash> txIds, ulong blockNumber)
        {
            var receipts = new List <TransactionReceipt>();

            foreach (var txId in txIds)
            {
                if (_allTxns.TryGetValue(txId, out var tr))
                {
                    tr.Status = TransactionReceipt.Types.TransactionStatus.TransactionExecuted;
                    tr.ExecutedBlockNumber = blockNumber;
                    _transactionManager.AddTransactionAsync(tr.Transaction);
                    receipts.Add(tr);
                }
                else
                {
                    //TODO: Handle this, but it should never happen
                }
            }

            _receiptManager.AddOrUpdateReceiptsAsync(receipts);
        }
Exemple #11
0
        private async Task ProcessTransactionAsync(QueuedTransaction queuedTransaction)
        {
            try
            {
                if (_allTransactions.Count > _transactionOptions.PoolLimit)
                {
                    return;
                }

                if (_allTransactions.ContainsKey(queuedTransaction.TransactionId))
                {
                    return;
                }

                if (!queuedTransaction.Transaction.VerifyExpiration(_bestChainHeight))
                {
                    Logger.LogWarning($"Transaction {queuedTransaction.TransactionId} already expired.");
                    return;
                }

                var validationResult =
                    await _transactionValidationService.ValidateTransactionWhileCollectingAsync(queuedTransaction
                                                                                                .Transaction);

                if (!validationResult)
                {
                    Logger.LogWarning($"Transaction {queuedTransaction.TransactionId} validation failed.");
                    return;
                }

                var hasTransaction = await _blockchainService.HasTransactionAsync(queuedTransaction.TransactionId);

                if (hasTransaction)
                {
                    return;
                }

                await _transactionManager.AddTransactionAsync(queuedTransaction.Transaction);

                var addSuccess = _allTransactions.TryAdd(queuedTransaction.TransactionId, queuedTransaction);
                if (!addSuccess)
                {
                    Logger.LogWarning($"Transaction {queuedTransaction.TransactionId} insert failed.");
                    return;
                }

                var prefix = await GetPrefixByHeightAsync(queuedTransaction.Transaction.RefBlockNumber, _bestChainHash);

                UpdateRefBlockStatus(queuedTransaction, prefix, _bestChainHeight);

                if (queuedTransaction.RefBlockStatus == RefBlockStatus.RefBlockExpired)
                {
                    return;
                }

                if (queuedTransaction.RefBlockStatus == RefBlockStatus.RefBlockValid)
                {
                    await LocalEventBus.PublishAsync(new TransactionAcceptedEvent()
                    {
                        Transaction = queuedTransaction.Transaction
                    });
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Process transaction failed.");
            }
        }
Exemple #12
0
        public async Task HandleTransactionsReceivedAsync(TransactionsReceivedEvent eventData)
        {
            foreach (var transaction in eventData.Transactions)
            {
                if (!transaction.VerifySignature())
                {
                    continue;
                }

                var receipt = new TransactionReceipt(transaction);
                if (_allTransactions.ContainsKey(receipt.TransactionId))
                {
                    Logger.LogWarning($"Transaction already exists in TxStore");
                    continue;
                }

                if (_allTransactions.Count > _transactionOptions.PoolLimit)
                {
                    Logger.LogWarning($"TxStore is full, ignore tx {receipt.TransactionId}");
                    break;
                }

                if (transaction.CalculateSize() > TransactionPoolConsts.TransactionSizeLimit)
                {
                    Logger.LogWarning($"Transaction {receipt.TransactionId} oversize {transaction.CalculateSize()}");
                    continue;
                }

                var txn = await _transactionManager.GetTransaction(receipt.TransactionId);

                if (txn != null)
                {
                    Logger.LogWarning($"Transaction already exists in TxStore");
                    continue;
                }

                var success = _allTransactions.TryAdd(receipt.TransactionId, receipt);
                if (!success)
                {
                    continue;
                }

                await _transactionManager.AddTransactionAsync(transaction);

                if (_bestChainHash == Hash.Empty)
                {
                    continue;
                }

                var prefix = await GetPrefixByHeightAsync(receipt.Transaction.RefBlockNumber, _bestChainHash);

                CheckPrefixForOne(receipt, prefix, _bestChainHeight);
                AddToRespectiveCurrentCollection(receipt);
                if (receipt.RefBlockStatus == RefBlockStatus.RefBlockValid)
                {
                    await LocalEventBus.PublishAsync(new TransactionAcceptedEvent()
                    {
                        Transaction = transaction
                    });
                }
            }
        }
Exemple #13
0
        public async Task HandleTransactionsReceivedAsync(TransactionsReceivedEvent eventData)
        {
            var executableTransactions = new List <Transaction>();

            foreach (var transaction in eventData.Transactions)
            {
                var receipt = new TransactionReceipt
                {
                    TransactionId = transaction.GetHash(),
                    Transaction   = transaction
                };
                if (_allTransactions.ContainsKey(receipt.TransactionId))
                {
                    //Logger.LogWarning($"Transaction already exists in TxStore");
                    continue;
                }

                if (_allTransactions.Count > _transactionOptions.PoolLimit)
                {
                    //Logger.LogWarning($"TxStore is full, ignore tx {receipt.TransactionId}");
                    break;
                }

                // Skip this transaction if it is already in local database.
                var txn = await _transactionManager.GetTransactionAsync(receipt.TransactionId);

                if (txn != null)
                {
                    continue;
                }

                var validationResult = await _transactionValidationService.ValidateTransactionAsync(transaction);

                if (!validationResult)
                {
                    continue;
                }

                var additionResult = _allTransactions.TryAdd(receipt.TransactionId, receipt);
                if (!additionResult)
                {
                    continue;
                }

                await _transactionManager.AddTransactionAsync(transaction);

                executableTransactions.Add(transaction);

                if (_bestChainHash == Hash.Empty)
                {
                    continue;
                }

                var prefix = await GetPrefixByHeightAsync(receipt.Transaction.RefBlockNumber, _bestChainHash);

                CheckPrefixForOne(receipt, prefix, _bestChainHeight);
                AddToRespectiveCurrentCollection(receipt);
                if (receipt.RefBlockStatus == RefBlockStatus.RefBlockValid)
                {
                    await LocalEventBus.PublishAsync(new TransactionAcceptedEvent()
                    {
                        Transaction = transaction
                    });
                }
            }
        }