public async Task ValidateTransactionTest()
        {
            TransactionValidationStatusChangedEvent transactionValidationStatusChangedEventData = null;

            _eventBus.Subscribe <TransactionValidationStatusChangedEvent>(d =>
            {
                transactionValidationStatusChangedEventData = d;
                return(Task.CompletedTask);
            });

            var kernelTestHelper = GetRequiredService <KernelTestHelper>();
            var transaction      = kernelTestHelper.GenerateTransaction();

            var result =
                await _transactionMethodValidationProvider.ValidateTransactionAsync(transaction, await _kernelTestHelper.GetChainContextAsync());

            result.ShouldBeTrue();

            transactionValidationStatusChangedEventData.ShouldBeNull();

            transaction.MethodName = "View";

            result =
                await _transactionMethodValidationProvider.ValidateTransactionAsync(transaction, await _kernelTestHelper.GetChainContextAsync());

            result.ShouldBeFalse();

            transactionValidationStatusChangedEventData.ShouldNotBeNull();
            transactionValidationStatusChangedEventData.TransactionResultStatus.ShouldBe(TransactionResultStatus.NodeValidationFailed);
            transactionValidationStatusChangedEventData.Error.ShouldBe("View transaction is not allowed.");
        }
        public async Task AddTransactions_Limit_Test()
        {
            TransactionValidationStatusChangedEvent transactionValidationStatusChangedEventData = null;

            _eventBus.Subscribe <TransactionValidationStatusChangedEvent>(d =>
            {
                transactionValidationStatusChangedEventData = d;
                return(Task.CompletedTask);
            });

            var chain = await _blockchainService.GetChainAsync();

            await _txHub.UpdateTransactionPoolByBestChainAsync(chain.BestChainHash, chain.BestChainHeight);

            for (var i = 0; i < 20; i++)
            {
                var tx = _kernelTestHelper.GenerateTransaction(chain.BestChainHeight, chain.BestChainHash);
                await AddTransactionsAsync(new[] { tx });
            }
            await _txHub.UpdateTransactionPoolByBestChainAsync(chain.BestChainHash, chain.BestChainHeight);

            await TransactionPoolSizeShouldBeAsync(20, 20);

            var transaction = _kernelTestHelper.GenerateTransaction(chain.BestChainHeight, chain.BestChainHash);

            await AddTransactionsAsync(new[] { transaction });
            await TransactionPoolSizeShouldBeAsync(20, 20);

            transactionValidationStatusChangedEventData.ShouldNotBeNull();
            transactionValidationStatusChangedEventData.TransactionId.ShouldBe(transaction.GetHash());
            transactionValidationStatusChangedEventData.TransactionResultStatus.ShouldBe(TransactionResultStatus
                                                                                         .NodeValidationFailed);
            transactionValidationStatusChangedEventData.Error.ShouldBe("Transaction Pool is full.");
        }
Exemple #3
0
        public async Task ValidateTransactionTest()
        {
            TransactionValidationStatusChangedEvent transactionValidationStatusChangedEventData = null;

            _eventBus.Subscribe <TransactionValidationStatusChangedEvent>(d =>
            {
                transactionValidationStatusChangedEventData = d;
                return(Task.CompletedTask);
            });

            TransactionExecutionValidationFailedEvent transactionExecutionValidationFailedEvent = null;

            _eventBus.Subscribe <TransactionExecutionValidationFailedEvent>(d =>
            {
                transactionExecutionValidationFailedEvent = d;
                return(Task.CompletedTask);
            });

            var transactionMockExecutionHelper = GetRequiredService <TransactionMockExecutionHelper>();

            transactionMockExecutionHelper.SetTransactionResultStatus(TransactionResultStatus.Mined);
            var kernelTestHelper = GetRequiredService <KernelTestHelper>();
            var transaction      = kernelTestHelper.GenerateTransaction();

            var result =
                await _transactionExecutionValidationProvider.ValidateTransactionAsync(transaction, await _kernelTestHelper.GetChainContextAsync());

            result.ShouldBeTrue();

            transactionValidationStatusChangedEventData.ShouldBeNull();
            transactionExecutionValidationFailedEvent.ShouldBeNull();
        }
        public async Task ValidateTransaction_Test()
        {
            TransactionValidationStatusChangedEvent eventData = null;

            _eventBus.Subscribe <TransactionValidationStatusChangedEvent>(d =>
            {
                eventData = d;
                return(Task.CompletedTask);
            });

            var transaction = _kernelTestHelper.GenerateTransaction();
            var result      =
                await _basicTransactionValidationProvider.ValidateTransactionAsync(transaction, new ChainContext());

            result.ShouldBeTrue();
            eventData.ShouldBeNull();

            transaction.Signature = ByteString.Empty;
            result =
                await _basicTransactionValidationProvider.ValidateTransactionAsync(transaction, new ChainContext());

            result.ShouldBeFalse();
            eventData.ShouldNotBeNull();
            eventData.TransactionId.ShouldBe(transaction.GetHash());
            eventData.TransactionResultStatus.ShouldBe(TransactionResultStatus.NodeValidationFailed);
            eventData.Error.ShouldBe("Incorrect transaction signature.");

            eventData   = null;
            transaction = GenerateBigTransaction();
            result      =
                await _basicTransactionValidationProvider.ValidateTransactionAsync(transaction, new ChainContext());

            result.ShouldBeFalse();
            eventData.ShouldNotBeNull();
            eventData.TransactionId.ShouldBe(transaction.GetHash());
            eventData.TransactionResultStatus.ShouldBe(TransactionResultStatus.NodeValidationFailed);
            eventData.Error.ShouldBe("Transaction size exceeded.");
        }
        public async Task TxHub_Test()
        {
            TransactionValidationStatusChangedEvent transactionValidationStatusChangedEventData = null;

            _eventBus.Subscribe <TransactionValidationStatusChangedEvent>(d =>
            {
                transactionValidationStatusChangedEventData = d;
                return(Task.CompletedTask);
            });

            TransactionAcceptedEvent transactionAcceptedEvent = null;

            _eventBus.Subscribe <TransactionAcceptedEvent>(d =>
            {
                transactionAcceptedEvent = d;
                return(Task.CompletedTask);
            });

            {
                // Empty transaction pool
                // Chain:
                //         BestChainHeight: 11
                // TxHub:
                //         BestChainHeight: 0
                //          AllTransaction: 0
                //    ValidatedTransaction: 0
                await TxHubBestChainShouldBeAsync(Hash.Empty, 0);
                await TransactionPoolSizeShouldBeAsync(0, 0);

                transactionValidationStatusChangedEventData.ShouldBeNull();
                transactionAcceptedEvent.ShouldBeNull();
            }

            {
                // Receive a valid transaction
                // Chain:
                //         BestChainHeight: 11
                // TxHub:
                //         BestChainHeight: 0
                //          AllTransaction: 0
                //    ValidatedTransaction: 0
                var chain = await _blockchainService.GetChainAsync();

                var transactionValid =
                    _kernelTestHelper.GenerateTransaction(chain.BestChainHeight, chain.BestChainHash);

                await AddTransactionsAsync(new List <Transaction> {
                    transactionValid
                });
                await TxHubBestChainShouldBeAsync(Hash.Empty, 0);
                await TransactionPoolSizeShouldBeAsync(0, 0);
                await CheckTransactionInPoolAsync(transactionValid, false);

                transactionValidationStatusChangedEventData.ShouldBeNull();
                transactionAcceptedEvent.ShouldBeNull();
            }

            {
                // Receive best chain found event
                // Chain:
                //         BestChainHeight: 12
                // TxHub:
                //         BestChainHeight: 12
                //          AllTransaction: 0
                //    ValidatedTransaction: 0
                await _kernelTestHelper.AttachBlockToBestChain();

                var chain = await _blockchainService.GetChainAsync();

                await _txHub.UpdateTransactionPoolByBestChainAsync(chain.BestChainHash, chain.BestChainHeight);
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 12);
                await TransactionPoolSizeShouldBeAsync(0, 0);
            }

            {
                // Receive a different branch transaction
                // Chain:
                //         BestChainHeight: 12
                // TxHub:
                //         BestChainHeight: 12
                //          AllTransaction: 1
                //    ValidatedTransaction: 0
                var transactionDifferent = _kernelTestHelper.GenerateTransaction(12);
                var chain = await _blockchainService.GetChainAsync();
                await AddTransactionsAsync(new List <Transaction> {
                    transactionDifferent
                });
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 12);
                await TransactionPoolSizeShouldBeAsync(1, 0);
                await CheckTransactionInPoolAsync(transactionDifferent, true);

                transactionValidationStatusChangedEventData.ShouldBeNull();
                transactionAcceptedEvent.ShouldBeNull();
            }

            {
                // Receive a future transaction
                // Chain:
                //         BestChainHeight: 12
                // TxHub:
                //         BestChainHeight: 12
                //          AllTransaction: 1
                //    ValidatedTransaction: 0
                var chain = await _blockchainService.GetChainAsync();

                var transactionFuture = _kernelTestHelper.GenerateTransaction(chain.BestChainHeight + 1);
                await AddTransactionsAsync(new List <Transaction> {
                    transactionFuture
                });
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 12);
                await TransactionPoolSizeShouldBeAsync(1, 0);
                await CheckTransactionInPoolAsync(transactionFuture, false);

                transactionAcceptedEvent.ShouldBeNull();
                transactionValidationStatusChangedEventData.ShouldNotBeNull();
                transactionValidationStatusChangedEventData.TransactionId.ShouldBe(transactionFuture.GetHash());
                transactionValidationStatusChangedEventData.TransactionResultStatus.ShouldBe(TransactionResultStatus
                                                                                             .NodeValidationFailed);
                transactionValidationStatusChangedEventData.Error.ShouldContain("Transaction expired");

                transactionValidationStatusChangedEventData = null;
            }

            {
                // Receive a invalid transaction
                // Chain:
                //         BestChainHeight: 12
                // TxHub:
                //         BestChainHeight: 12
                //          AllTransaction: 1
                //    ValidatedTransaction: 0
                var chain = await _blockchainService.GetChainAsync();

                var transactionInvalid =
                    _kernelTestHelper.GenerateTransaction(chain.BestChainHeight, chain.BestChainHash);
                transactionInvalid.Signature = ByteString.Empty;
                await AddTransactionsAsync(new List <Transaction> {
                    transactionInvalid
                });
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 12);
                await TransactionPoolSizeShouldBeAsync(1, 0);
                await CheckTransactionInPoolAsync(transactionInvalid, false);

                transactionValidationStatusChangedEventData.ShouldNotBeNull();
                transactionValidationStatusChangedEventData.TransactionId.ShouldBe(transactionInvalid.GetHash());
                transactionValidationStatusChangedEventData.TransactionResultStatus.ShouldBe(TransactionResultStatus
                                                                                             .NodeValidationFailed);
                transactionValidationStatusChangedEventData.Error.ShouldBe("Incorrect transaction signature.");
                transactionAcceptedEvent.ShouldBeNull();

                transactionValidationStatusChangedEventData = null;
            }

            {
                // Receive a transaction already in DB
                // Chain:
                //         BestChainHeight: 12
                // TxHub:
                //         BestChainHeight: 12
                //          AllTransaction: 1
                //    ValidatedTransaction: 0
                var chain = await _blockchainService.GetChainAsync();

                var transactionInDB =
                    _kernelTestHelper.GenerateTransaction(chain.BestChainHeight, chain.BestChainHash);
                await _blockchainService.AddTransactionsAsync(new List <Transaction> {
                    transactionInDB
                });
                await AddTransactionsAsync(new List <Transaction> {
                    transactionInDB
                });
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 12);
                await TransactionPoolSizeShouldBeAsync(1, 0);
                await CheckTransactionInPoolAsync(transactionInDB, false);

                transactionValidationStatusChangedEventData.ShouldBeNull();
                transactionAcceptedEvent.ShouldBeNull();
            }

            {
                // Receive a valid transaction
                // Chain:
                //         BestChainHeight: 12
                // TxHub:
                //         BestChainHeight: 12
                //          AllTransaction: 2
                //    ValidatedTransaction: 1
                var chain = await _blockchainService.GetChainAsync();

                var transactionValid =
                    _kernelTestHelper.GenerateTransaction(chain.BestChainHeight, chain.BestChainHash);

                await AddTransactionsAsync(new List <Transaction> {
                    transactionValid
                });

                await _txHub.UpdateTransactionPoolByBestChainAsync(chain.BestChainHash, chain.BestChainHeight);
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 12);
                await TransactionPoolSizeShouldBeAsync(2, 1);
                await CheckTransactionInPoolAsync(transactionValid, true);

                transactionValidationStatusChangedEventData.ShouldBeNull();
                transactionAcceptedEvent.ShouldNotBeNull();
                transactionAcceptedEvent.Transaction.ShouldBe(transactionValid);
                transactionAcceptedEvent.ChainId.ShouldBe(chain.Id);

                transactionAcceptedEvent = null;

                // Receive the valid transaction again
                // Chain:
                //         BestChainHeight: 12
                // TxHub:
                //         BestChainHeight: 12
                //          AllTransaction: 2
                //    ValidatedTransaction: 1
                await AddTransactionsAsync(new List <Transaction> {
                    transactionValid
                });
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 12);
                await TransactionPoolSizeShouldBeAsync(2, 1);
                await CheckTransactionInPoolAsync(transactionValid, true);

                transactionValidationStatusChangedEventData.ShouldBeNull();
                transactionAcceptedEvent.ShouldBeNull();

                // Mined a block
                // Chain:
                //         BestChainHeight: 13
                // TxHub:
                //         BestChainHeight: 12
                //          AllTransaction: 1
                //    ValidatedTransaction: 0
                var transactionNotInPool =
                    _kernelTestHelper.GenerateTransaction(chain.BestChainHeight, chain.BestChainHash);

                var newBlock = await _kernelTestHelper.AttachBlockToBestChain(new List <Transaction>
                {
                    transactionValid,
                    transactionNotInPool
                });

                await _txHub.CleanByTransactionIdsAsync(newBlock.TransactionIds);
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 12);
                await TransactionPoolSizeShouldBeAsync(1, 1);
                await CheckTransactionInPoolAsync(transactionValid, false);
            }

            {
                // Receive best chain found event
                // Chain:
                //         BestChainHeight: 13
                // TxHub:
                //         BestChainHeight: 13
                //          AllTransaction: 1
                //    ValidatedTransaction: 0
                var chain = await _blockchainService.GetChainAsync();

                await _txHub.UpdateTransactionPoolByBestChainAsync(chain.BestChainHash, chain.BestChainHeight);

                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 13);
                await TransactionPoolSizeShouldBeAsync(1, 0);
            }

            {
                // Receive a valid transaction and a expired transaction
                // Chain:
                //         BestChainHeight: 13
                // TxHub:
                //         BestChainHeight: 13
                //          AllTransaction: 2
                //    ValidatedTransaction: 1
                var chain = await _blockchainService.GetChainAsync();

                var transactionValid =
                    _kernelTestHelper.GenerateTransaction(chain.BestChainHeight, chain.BestChainHash);
                var transactionExpired = _kernelTestHelper.GenerateTransaction(chain.BestChainHeight + 100);

                await AddTransactionsAsync(new List <Transaction>
                {
                    transactionValid,
                    transactionExpired
                });

                await _txHub.UpdateTransactionPoolByBestChainAsync(chain.BestChainHash, chain.BestChainHeight);
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 13);
                await TransactionPoolSizeShouldBeAsync(2, 1);
                await CheckTransactionInPoolAsync(transactionValid, true);
                await CheckTransactionInPoolAsync(transactionExpired, false);

                transactionValidationStatusChangedEventData.ShouldNotBeNull();
                transactionValidationStatusChangedEventData.TransactionId.ShouldBe(transactionExpired.GetHash());
                transactionValidationStatusChangedEventData.TransactionResultStatus.ShouldBe(TransactionResultStatus
                                                                                             .NodeValidationFailed);
                transactionValidationStatusChangedEventData.Error.ShouldContain("Transaction expired");

                transactionAcceptedEvent.ShouldNotBeNull();
                transactionAcceptedEvent.Transaction.ShouldBe(transactionValid);
                transactionAcceptedEvent.ChainId.ShouldBe(chain.Id);

                transactionAcceptedEvent = null;
                transactionValidationStatusChangedEventData = null;
            }

            {
                // Set lib 12
                // Chain:
                //         BestChainHeight: 13
                // TxHub:
                //         BestChainHeight: 13
                //          AllTransaction: 1
                //    ValidatedTransaction: 1
                var chain = await _blockchainService.GetChainAsync();

                await _txHub.CleanByHeightAsync(12);
                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 13);
                await TransactionPoolSizeShouldBeAsync(1, 1);
            }

            {
                // After 513 blocks
                // Chain:
                //         BestChainHeight: 526
                // TxHub:
                //         BestChainHeight: 526
                //          AllTransaction: 1
                //    ValidatedTransaction: 0
                var chain = await _blockchainService.GetChainAsync();

                var bestChainHeight = chain.BestChainHeight;
                for (var i = 0; i < KernelConstants.ReferenceBlockValidPeriod + 1; i++)
                {
                    var transaction = _kernelTestHelper.GenerateTransaction(bestChainHeight + i);
                    await _kernelTestHelper.AttachBlockToBestChain(new List <Transaction> {
                        transaction
                    });

                    chain = await _blockchainService.GetChainAsync();

                    await _txHub.UpdateTransactionPoolByBestChainAsync(chain.BestChainHash, chain.BestChainHeight);
                }

                await TxHubBestChainShouldBeAsync(chain.BestChainHash, 526);

                await TransactionPoolSizeShouldBeAsync(0, 0);
            }
        }