public async Task TransactionReadOnlyExecutionServiceExtensions_Test()
        {
            var chain = await BlockchainService.GetChainAsync();

            var context = new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };
            var transaction = OsTestHelper.GenerateTransaction(SampleAddress.AddressList[0],
                                                               SmartContractAddressService.GetAddressByContractName(TokenSmartContractAddressNameProvider.Name),
                                                               "GetBalance", new GetBalanceInput
            {
                Owner  = SampleAddress.AddressList[0],
                Symbol = "ELF"
            });

            var result = await TransactionReadOnlyExecutionService.ExecuteAsync <GetBalanceOutput>(context, transaction,
                                                                                                   TimestampHelper.GetUtcNow(),
                                                                                                   true);

            result.Balance.ShouldBe(0);
            result.Symbol.ShouldBe("ELF");

            //without such method and call
            transaction.MethodName = "NotExist";
            await Should.ThrowAsync <SmartContractExecutingException>(async() =>
            {
                await TransactionReadOnlyExecutionService.ExecuteAsync <GetBalanceOutput>(context, transaction,
                                                                                          TimestampHelper.GetUtcNow(),
                                                                                          true);
            });
        }
        public async Task ParallelExecuteAsync_Test()
        {
            var chain = await BlockchainService.GetChainAsync();

            (PrepareTransactions, KeyPairs) = await OsTestHelper.PrepareTokenForParallel(10);

            Block = OsTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, PrepareTransactions);
            //await BlockExecutingService.ExecuteBlockAsync(Block.Header, PrepareTransactions);
            await OsTestHelper.BroadcastTransactions(PrepareTransactions);

            Block = await MinerService.MineAsync(chain.BestChainHash, chain.BestChainHeight,
                                                 TimestampHelper.GetUtcNow(), TimestampHelper.DurationFromSeconds(4));

            await BlockchainService.AddBlockAsync(Block);

            await BlockAttachService.AttachBlockAsync(Block);

            SystemTransactions = await OsTestHelper.GenerateTransferTransactions(1);

            CancellableTransactions = OsTestHelper.GenerateTransactionsWithoutConflict(KeyPairs);
            Block = OsTestHelper.GenerateBlock(Block.GetHash(), Block.Height,
                                               SystemTransactions.Concat(CancellableTransactions));

            await OsTestHelper.BroadcastTransactions(SystemTransactions.Concat(CancellableTransactions));

            var block = await BlockExecutingService.ExecuteBlockAsync(Block.Header,
                                                                      SystemTransactions, CancellableTransactions, CancellationToken.None);

            block.TransactionIds.Count().ShouldBeGreaterThan(10);
        }
        public async Task IsViewTransactionAsync_Test()
        {
            var chain = await BlockchainService.GetChainAsync();

            var context = new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };
            var transaction = OsTestHelper.GenerateTransaction(SampleAddress.AddressList[0],
                                                               await SmartContractAddressService.GetAddressByContractNameAsync(context, TokenSmartContractAddressNameProvider.StringName),
                                                               "GetBalance", new GetBalanceInput
            {
                Owner  = SampleAddress.AddressList[0],
                Symbol = "ELF"
            });

            var result = await TransactionReadOnlyExecutionService.IsViewTransactionAsync(context, transaction);

            result.ShouldBeTrue();

            transaction = OsTestHelper.GenerateTransaction(SampleAddress.AddressList[0],
                                                           await SmartContractAddressService.GetAddressByContractNameAsync(context,
                                                                                                                           TokenSmartContractAddressNameProvider.StringName),
                                                           "Transfer", new TransferInput
            {
                To     = SampleAddress.AddressList[1],
                Symbol = "ELF",
                Amount = 10
            });
            result = await TransactionReadOnlyExecutionService.IsViewTransactionAsync(context, transaction);

            result.ShouldBeFalse();
        }
        public async Task ExecuteAsync_Test()
        {
            var chain = await BlockchainService.GetChainAsync();

            (PrepareTransactions, KeyPairs) = await OsTestHelper.PrepareTokenForParallel(10);

            Block = OsTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, PrepareTransactions);
            PrepareTransactions[0].To = SampleAccount.Accounts[0].Address;
            await OsTestHelper.BroadcastTransactions(PrepareTransactions);

            var executionReturnSets = await _transactionExecutingService.ExecuteAsync(new TransactionExecutingDto
            {
                Transactions = PrepareTransactions,
                BlockHeader  = Block.Header
            }, CancellationToken.None);

            executionReturnSets.Count.ShouldBe(PrepareTransactions.Count);
            executionReturnSets.Count(set => set.TransactionResult.Status == TransactionResultStatus.Failed)
            .ShouldBe(1);
            executionReturnSets.First(set => set.TransactionResult.Status == TransactionResultStatus.Failed).TransactionResult.Error.ShouldBe("Invalid contract address.");
            executionReturnSets.Count(set => set.TransactionResult.Status == TransactionResultStatus.Mined).ShouldBe(9);

            (PrepareTransactions, KeyPairs) = await OsTestHelper.PrepareTokenForParallel(10);

            Block = OsTestHelper.GenerateBlock(Block.GetHash(), Block.Height, PrepareTransactions);
            await OsTestHelper.BroadcastTransactions(PrepareTransactions);

            var cancelTokenSource = new CancellationTokenSource();

            cancelTokenSource.Cancel();
            executionReturnSets = await _transactionExecutingService.ExecuteAsync(new TransactionExecutingDto
            {
                Transactions = PrepareTransactions,
                BlockHeader  = Block.Header
            }, cancelTokenSource.Token);

            executionReturnSets.Count.ShouldBe(0);

            (PrepareTransactions, KeyPairs) = await OsTestHelper.PrepareTokenForParallel(10);

            Block = OsTestHelper.GenerateBlock(Block.GetHash(), Block.Height, PrepareTransactions);
            _systemTransactionExtraDataProvider.SetSystemTransactionCount(1, Block.Header);
            executionReturnSets = await _transactionExecutingService.ExecuteAsync(new TransactionExecutingDto
            {
                Transactions = PrepareTransactions,
                BlockHeader  = Block.Header
            }, CancellationToken.None);

            executionReturnSets.Count.ShouldBe(PrepareTransactions.Count);
            executionReturnSets.ShouldAllBe(set => set.TransactionResult.Status == TransactionResultStatus.Mined);
        }
        public async Task GetTransactionParametersAsync_Test()
        {
            var chain = await BlockchainService.GetChainAsync();

            var context = new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };
            var transaction = await OsTestHelper.GenerateTransferTransaction();

            var jsonResult =
                await TransactionReadOnlyExecutionService.GetTransactionParametersAsync(context, transaction);

            jsonResult.ShouldNotBeEmpty();
            jsonResult.ShouldContain("to");
            jsonResult.ShouldContain("symbol");
            jsonResult.ShouldContain("amount");
        }