private async Task <bool> TryExecuteBlockAsync(Block block)
        {
            var blockHash = block.GetHash();

            var blockState = await _blockStateSetManger.GetBlockStateSetAsync(blockHash);

            if (blockState != null)
            {
                return(true);
            }

            var transactions = await _blockchainService.GetTransactionsAsync(block.TransactionIds);

            var executedBlock = await _blockExecutingService.ExecuteBlockAsync(block.Header, transactions);

            var blockHashWithoutCache = executedBlock.GetHashWithoutCache();

            if (blockHashWithoutCache != blockHash)
            {
                blockState = await _blockStateSetManger.GetBlockStateSetAsync(blockHashWithoutCache);

                Logger.LogWarning($"Block execution failed. BlockStateSet: {blockState}");
                Logger.LogWarning(
                    $"Block execution failed. Block header: {executedBlock.Header}, Block body: {executedBlock.Body}");

                return(false);
            }

            return(true);
        }
        public async Task TransactionLimitSetAndGet_Test()
        {
            var chain = await _blockchainService.GetChainAsync();

            var blockExecutedDataKey = "BlockExecutedData/BlockTransactionLimit";
            var blockStateSet        = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldNotContainKey(blockExecutedDataKey);

            await _blockTransactionLimitProvider.SetLimitAsync(new BlockIndex
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            }, 50);

            blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldContainKey(blockExecutedDataKey);

            var limit = await _blockTransactionLimitProvider.GetLimitAsync(
                new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            });

            limit.ShouldBe(50);
        }
        public async Task GlobalSetup()
        {
            _chains = GetRequiredService <IBlockchainStore <Chain> >();
            _chainStateInfoCollection = GetRequiredService <IStateStore <ChainStateInfo> >();
            _blockchainStateService   = GetRequiredService <IBlockchainStateService>();
            _blockStateSetManger      = GetRequiredService <IBlockStateSetManger>();
            _blockchainService        = GetRequiredService <IBlockchainService>();
            _osTestHelper             = GetRequiredService <OSTestHelper>();
            _chainManager             = GetRequiredService <IChainManager>();
            _blockManager             = GetRequiredService <IBlockManager>();
            _transactionManager       = GetRequiredService <ITransactionManager>();
            _transactionPoolService   = GetRequiredService <ITransactionPoolService>();


            _blockStateSets = new List <BlockStateSet>();
            _blocks         = new List <Block>();

            _chain = await _blockchainService.GetChainAsync();

            var blockHash = _chain.BestChainHash;

            while (true)
            {
                var blockState = await _blockStateSetManger.GetBlockStateSetAsync(blockHash);

                _blockStateSets.Add(blockState);

                var blockHeader = await _blockchainService.GetBlockHeaderByHashAsync(blockHash);

                blockHash = blockHeader.PreviousBlockHash;
                if (blockHash == _chain.LastIrreversibleBlockHash)
                {
                    break;
                }
            }

            await _blockchainStateService.MergeBlockStateAsync(_chain.BestChainHeight, _chain.BestChainHash);

            for (var i = 0; i < BlockCount; i++)
            {
                var transactions = await _osTestHelper.GenerateTransferTransactions(TransactionCount);

                await _osTestHelper.BroadcastTransactions(transactions);

                var block = await _osTestHelper.MinedOneBlock();

                _blocks.Add(block);

                var blockState = await _blockStateSetManger.GetBlockStateSetAsync(block.GetHash());

                _blockStateSets.Add(blockState);
            }

            var chain = await _blockchainService.GetChainAsync();

            await _chainManager.SetIrreversibleBlockAsync(chain, chain.BestChainHash);

            _chainStateInfo = await _chainStateInfoCollection.GetAsync(chain.Id.ToStorageKey());
        }
        public async Task MergeBlockState_WithStatus_Merging()
        {
            await _blockStateSetManger.SetBlockStateSetAsync(new BlockStateSet()
            {
                BlockHash    = _tv[0].BlockHash,
                BlockHeight  = _tv[0].BlockHeight,
                PreviousHash = Hash.FromString("PreviousHash"),
                Changes      =
                {
                    {
                        _tv[1].Key,
                        _tv[1].Value
                    }
                }
            });

            await _blockStateSetManger.SetBlockStateSetAsync(new BlockStateSet()
            {
                BlockHash    = _tv[1].BlockHash,
                BlockHeight  = _tv[1].BlockHeight,
                PreviousHash = _tv[0].BlockHash,
                Changes      =
                {
                    {
                        _tv[1].Key,
                        _tv[1].Value
                    }
                }
            });

            var chainStateInfo = new ChainStateInfo
            {
                BlockHash        = _tv[0].BlockHash,
                BlockHeight      = _tv[0].BlockHeight,
                MergingBlockHash = _tv[1].BlockHash,
                Status           = ChainStateMergingStatus.Merging
            };

            await _blockStateSetManger.MergeBlockStateAsync(chainStateInfo, _tv[1].BlockHash);

            chainStateInfo = await _blockStateSetManger.GetChainStateInfoAsync();

            chainStateInfo.BlockHash.ShouldBe(_tv[1].BlockHash);
            chainStateInfo.BlockHeight.ShouldBe(_tv[1].BlockHeight);
            chainStateInfo.Status.ShouldBe(ChainStateMergingStatus.Common);
            chainStateInfo.MergingBlockHash.ShouldBeNull();

            var blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(_tv[1].BlockHash);

            blockStateSet.ShouldBeNull();
        }
예제 #5
0
        public async Task NonparallelContractCodeSetAndGet_Test()
        {
            var chain = await _blockchainService.GetChainAsync();

            var blockExecutedDataKey = $"BlockExecutedData/NonparallelContractCode/{SampleAddress.AddressList[0]}";
            var blockStateSet        = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldNotContainKey(blockExecutedDataKey);

            var nonparallelContractCode = new NonparallelContractCode
            {
                CodeHash = HashHelper.ComputeFrom(blockExecutedDataKey)
            };

            var dictionary = new Dictionary <Address, NonparallelContractCode>
            {
                { SampleAddress.AddressList[0], nonparallelContractCode }
            };

            await _nonparallelContractCodeProvider.SetNonparallelContractCodeAsync(new BlockIndex
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            }, dictionary);

            blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldContainKey(blockExecutedDataKey);

            _blockchainExecutedDataCacheProvider.TryGetChangeHeight(blockExecutedDataKey, out _).ShouldBeTrue();

            var nonparallelContractCodeFromState = await _nonparallelContractCodeProvider.GetNonparallelContractCodeAsync(
                new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            }, SampleAddress.AddressList[0]);

            nonparallelContractCodeFromState.ShouldBe(nonparallelContractCode);

            await _cleanBlockExecutedDataChangeHeightEventHandler.HandleEventAsync(
                new CleanBlockExecutedDataChangeHeightEventData
            {
                IrreversibleBlockHeight = chain.BestChainHeight
            });

            _blockchainExecutedDataCacheProvider.TryGetChangeHeight(blockExecutedDataKey, out _).ShouldBeFalse();
        }
        private async Task <BlockExecutedSet> ExecuteBlockAsync(Block block)
        {
            var blockHash = block.GetHash();

            var blockState = await _blockStateSetManger.GetBlockStateSetAsync(blockHash);

            if (blockState != null)
            {
                Logger.LogDebug($"Block already executed. block hash: {blockHash}");
                return(await GetExecuteBlockSetAsync(block, blockHash));
            }

            var transactions = await _blockchainService.GetTransactionsAsync(block.TransactionIds);

            var blockExecutedSet = await _blockExecutingService.ExecuteBlockAsync(block.Header, transactions);

            var executedBlock = blockExecutedSet.Block;

            var blockHashWithoutCache = executedBlock.GetHashWithoutCache();

            if (blockHashWithoutCache == blockHash)
            {
                return(blockExecutedSet);
            }
            Logger.LogDebug(
                $"Block execution failed. Expected: {block}, actual: {executedBlock}");
            return(null);
        }
        public async Task SmartContractAddress_Set_And_Get_Test()
        {
            var chain = await _smartContractHelper.CreateChainAsync();

            var contractName = Hash.Empty.ToStorageKey();

            var chainContext = new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };

            var smartContractAddress =
                await _smartContractAddressProvider.GetSmartContractAddressAsync(chainContext, contractName);

            smartContractAddress.ShouldBeNull();

            await _smartContractAddressProvider.SetSmartContractAddressAsync(chainContext, contractName,
                                                                             SampleAddress.AddressList[0]);

            var blockExecutedDataKey = $"BlockExecutedData/SmartContractAddress/{contractName}";
            var blockStateSet        = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldContainKey(blockExecutedDataKey);

            smartContractAddress =
                await _smartContractAddressProvider.GetSmartContractAddressAsync(chainContext, contractName);

            smartContractAddress.Address.ShouldBe(SampleAddress.AddressList[0]);
            smartContractAddress.BlockHeight = chainContext.BlockHeight;
            smartContractAddress.BlockHash   = chainContext.BlockHash;
        }
        public async Task GetStateAsync_Test()
        {
            var chain = await _smartContractHelper.CreateChainAsync();

            await Assert.ThrowsAsync <InvalidOperationException>(() => _smartContractBridgeService.GetStateAsync(
                                                                     SampleAddress.AddressList[0], string.Empty,
                                                                     chain.BestChainHeight,
                                                                     chain.BestChainHash));


            var scopedStatePath = new ScopedStatePath
            {
                Address = SampleAddress.AddressList[0],
                Path    = new StatePath
                {
                    Parts = { "part" }
                }
            };
            var state = await _smartContractBridgeService.GetStateAsync(SampleAddress.AddressList[0], scopedStatePath.ToStateKey(),
                                                                        chain.BestChainHeight, chain.BestChainHash);

            state.ShouldBeNull();

            var blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.Changes[scopedStatePath.ToStateKey()] = ByteString.Empty;
            await _blockStateSetManger.SetBlockStateSetAsync(blockStateSet);

            state = await _smartContractBridgeService.GetStateAsync(SampleAddress.AddressList[0], scopedStatePath.ToStateKey(),
                                                                    chain.BestChainHeight, chain.BestChainHash);

            state.ShouldBe(ByteString.Empty);
        }
        /// <summary>
        /// Get the current state about a given block
        /// </summary>
        /// <param name="blockHash">block hash</param>
        /// <returns></returns>
        public async Task <BlockStateDto> GetBlockStateAsync(string blockHash)
        {
            var blockState = await _blockStateSetManger.GetBlockStateSetAsync(Hash.LoadFromHex(blockHash));

            if (blockState == null)
            {
                throw new UserFriendlyException(Error.Message[Error.NotFound], Error.NotFound.ToString());
            }

            return(_objectMapper.Map <BlockStateSet, BlockStateDto>(blockState));
        }
예제 #10
0
        /// <summary>
        /// Get the current state about a given block
        /// </summary>
        /// <param name="blockHash">block hash</param>
        /// <returns></returns>
        public async Task <BlockStateDto> GetBlockStateAsync(string blockHash)
        {
            var blockState = await _blockStateSetManger.GetBlockStateSetAsync(HashHelper.HexStringToHash(blockHash));

            if (blockState == null)
            {
                throw new UserFriendlyException(Error.Message[Error.NotFound], Error.NotFound.ToString());
            }

            return(JsonConvert.DeserializeObject <BlockStateDto>(blockState.ToString()));
        }
예제 #11
0
        public async Task NonparallelContractCodeSetAndGet_Test()
        {
            var chain = await _blockchainService.GetChainAsync();

            var blockExecutedDataKey = $"BlockExecutedData/NonparallelContractCode/{SampleAddress.AddressList[0]}";
            var blockStateSet        = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldNotContainKey(blockExecutedDataKey);

            var nonparallelContractCode = new NonparallelContractCode
            {
                CodeHash = Hash.FromString(blockExecutedDataKey)
            };

            var dictionary = new Dictionary <Address, NonparallelContractCode>
            {
                { SampleAddress.AddressList[0], nonparallelContractCode }
            };

            await _nonparallelContractCodeProvider.SetNonparallelContractCodeAsync(new BlockIndex
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            }, dictionary);

            blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldContainKey(blockExecutedDataKey);

            var nonparallelContractCodeFromState = await _nonparallelContractCodeProvider.GetNonparallelContractCodeAsync(
                new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            }, SampleAddress.AddressList[0]);

            nonparallelContractCodeFromState.ShouldBe(nonparallelContractCode);
        }
예제 #12
0
        public async Task AddBlockExecutedCacheAsync(Hash blockHash, IDictionary <string, ByteString> blockExecutedCache)
        {
            var blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(blockHash);

            if (blockStateSet == null)
            {
                return;
            }
            foreach (var keyPair in blockExecutedCache)
            {
                blockStateSet.BlockExecutedData[keyPair.Key] = keyPair.Value;
            }

            await _blockStateSets.SetWithCacheAsync(blockStateSet.BlockHash.ToStorageKey(), blockStateSet);
        }
예제 #13
0
        private async Task CheckBlockExecutedSetAsync(BlockExecutedSet blockExecutedSet, int transactionCount)
        {
            blockExecutedSet.Block.Body.TransactionIds.Count.ShouldBe(transactionCount);
            blockExecutedSet.TransactionResultMap.Values.Select(t => t.Status)
            .ShouldAllBe(status => status == TransactionResultStatus.Mined);
            var blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(blockExecutedSet.GetHash());

            blockStateSet.ShouldNotBeNull();
            var transactionResults = await _transactionResultManager.GetTransactionResultsAsync(
                blockExecutedSet.TransactionIds.ToList(),
                blockExecutedSet.GetHash());

            transactionResults.Count.ShouldBe(transactionCount);
            foreach (var transactionResult in transactionResults)
            {
                blockExecutedSet.TransactionResultMap[transactionResult.TransactionId].ShouldBe(transactionResult);
            }
        }
예제 #14
0
        public async Task BlockExecutedData_Test()
        {
            var genesisBlock = _kernelTestHelper.GenerateBlock(0, Hash.Empty, new List <Transaction>());
            var chain        = await _blockchainService.CreateChainAsync(genesisBlock, new List <Transaction>());

            var blockStateSet = new BlockStateSet
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };
            await _blockStateSetManger.SetBlockStateSetAsync(blockStateSet);

            var chainKey   = GetBlockExecutedDataKey <Chain>();
            var dictionary = new Dictionary <string, ByteString>
            {
                { chainKey, ByteString.CopyFrom(SerializationHelper.Serialize(chain)) }
            };
            await _blockchainExecutedDataManager.AddBlockExecutedCacheAsync(blockStateSet.BlockHash, dictionary);

            var isInStore = await CheckExecutedDataInStoreAsync(blockStateSet, chainKey, dictionary[chainKey]);

            isInStore.ShouldBeFalse();

            await _blockchainStateService.MergeBlockStateAsync(chain.BestChainHeight, chain.BestChainHash);

            isInStore = await CheckExecutedDataInStoreAsync(blockStateSet, chainKey, dictionary[chainKey]);

            isInStore.ShouldBeTrue();

            blockStateSet = await AddBlockStateSetAsync(blockStateSet);

            isInStore = await CheckExecutedDataInStoreAsync(blockStateSet, chainKey, dictionary[chainKey]);

            isInStore.ShouldBeTrue();

            // BlockStateSet is not exist
            var notExistHash = HashHelper.ComputeFrom("NotExist");
            await _blockchainExecutedDataManager.AddBlockExecutedCacheAsync(notExistHash, dictionary);

            var stateSet = await _blockStateSetManger.GetBlockStateSetAsync(notExistHash);

            stateSet.ShouldBeNull();
        }
예제 #15
0
        public async Task SmartContractRegistrationSetAndGet_Test()
        {
            var genesisBlock = _kernelTestHelper.GenerateBlock(0, Hash.Empty, new List <Transaction>());
            var chain        = await _blockchainService.CreateChainAsync(genesisBlock, new List <Transaction>());

            var blockStateSet = new BlockStateSet
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };
            await _blockStateSetManger.SetBlockStateSetAsync(blockStateSet);

            var blockExecutedDataKey = $"BlockExecutedData/SmartContractRegistration/{SampleAddress.AddressList[0]}";

            blockStateSet.BlockExecutedData.ShouldNotContainKey(blockExecutedDataKey);

            var chainContext = new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };

            var smartContractRegistration = new SmartContractRegistration
            {
                CodeHash = Hash.FromString(blockExecutedDataKey),
                Category = KernelConstants.CodeCoverageRunnerCategory,
                Version  = 1
            };
            await _smartContractRegistrationProvider.SetSmartContractRegistrationAsync(chainContext,
                                                                                       SampleAddress.AddressList[0], smartContractRegistration);

            blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldContainKey(blockExecutedDataKey);

            var smartContractRegistrationFromState =
                await _smartContractRegistrationProvider.GetSmartContractRegistrationAsync(chainContext,
                                                                                           SampleAddress.AddressList[0]);

            smartContractRegistrationFromState.ShouldBe(smartContractRegistration);
        }
        public async Task SmartContractRegistrationSetAndGet_Test()
        {
            var chain = await _smartContractHelper.CreateChainAsync();

            var blockExecutedDataKey = $"BlockExecutedData/SmartContractRegistration/{SampleAddress.AddressList[0]}";

            var chainContext = new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };

            var smartContractRegistrationFromProvider =
                await _smartContractRegistrationProvider.GetSmartContractRegistrationAsync(chainContext,
                                                                                           SampleAddress.AddressList[0]);

            smartContractRegistrationFromProvider.ShouldBeNull();

            var smartContractRegistration = new SmartContractRegistration
            {
                CodeHash = HashHelper.ComputeFrom(blockExecutedDataKey),
                Category = KernelConstants.CodeCoverageRunnerCategory,
                Version  = 1
            };
            await _smartContractRegistrationProvider.SetSmartContractRegistrationAsync(chainContext,
                                                                                       SampleAddress.AddressList[0], smartContractRegistration);

            var blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            blockStateSet.BlockExecutedData.ShouldContainKey(blockExecutedDataKey);

            smartContractRegistrationFromProvider =
                await _smartContractRegistrationProvider.GetSmartContractRegistrationAsync(chainContext,
                                                                                           SampleAddress.AddressList[0]);

            smartContractRegistrationFromProvider.ShouldBe(smartContractRegistration);
        }
예제 #17
0
        public async Task WrongParallelTest()
        {
            var chain = await _blockchainService.GetChainAsync();

            await _blockchainService.SetIrreversibleBlockAsync(chain, chain.BestChainHeight, chain.BestChainHash);

            //prepare token for tx verify
            var(tokenTransactions, groupUsers) =
                await _parallelTestHelper.PrepareTokenForParallel(_groupCount, 1000_00000000);

            await _parallelTestHelper.BroadcastTransactions(tokenTransactions);

            var prepareBlock =
                _parallelTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, tokenTransactions);

            prepareBlock =
                (await _blockExecutingService.ExecuteBlockAsync(prepareBlock.Header,
                                                                tokenTransactions)).Block;
            await _blockchainService.AddBlockAsync(prepareBlock);

            await _blockAttachService.AttachBlockAsync(prepareBlock);

            chain = await _blockchainService.GetChainAsync();

            var transactions =
                _parallelTestHelper.GenerateBasicFunctionWithParallelTransactions(groupUsers, _transactionCount);
            var transferTransaction = await _parallelTestHelper.GenerateTransferTransaction(Address.FromPublicKey(groupUsers[1].PublicKey)
                                                                                            , "ELF", 10);

            transactions.Add(transferTransaction);
            await _parallelTestHelper.BroadcastTransactions(transactions);

            var otherTransactions        = _parallelTestHelper.GenerateBasicFunctionWithParallelTransactions(groupUsers, _transactionCount);
            var otherTransferTransaction = await _parallelTestHelper.GenerateTransferTransaction(Address.FromPublicKey(groupUsers[2].PublicKey)
                                                                                                 , "ELF", 10);

            otherTransactions.Add(otherTransferTransaction);
            await _parallelTestHelper.BroadcastTransactions(otherTransactions);

            var transferTransactions = await _parallelTestHelper.GenerateTransferTransactions(16);

            await _parallelTestHelper.BroadcastTransactions(transferTransactions);

            var poolSize = (await _txHub.GetTransactionPoolStatusAsync()).AllTransactionCount;

            poolSize.ShouldBe(transactions.Count * 2 + transferTransactions.Count);

            var groupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                transactions);

            groupedTransactions.Parallelizables.Count.ShouldBe(_transactionCount + 1);
            groupedTransactions.NonParallelizables.Count.ShouldBe(0);
            for (var i = 0; i < transactions.Count; i++)
            {
                transactions[i].GetHash().ShouldBe(groupedTransactions.Parallelizables[i][0].GetHash());
            }

            var otherGroupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                otherTransactions);

            otherGroupedTransactions.Parallelizables.Count.ShouldBe(_transactionCount + 1);
            otherGroupedTransactions.NonParallelizables.Count.ShouldBe(0);

            var groupedTransferTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                transferTransactions);

            groupedTransferTransactions.Parallelizables.Count.ShouldBe(1);
            groupedTransferTransactions.Parallelizables[0].Count.ShouldBe(transferTransactions.Count);
            groupedTransferTransactions.NonParallelizables.Count.ShouldBe(0);

            _localEventBus.Subscribe <ConflictingTransactionsFoundInParallelGroupsEvent>(e =>
            {
                e.ConflictingSets.Count.ShouldBe(_groupCount + 1);
                e.ExistingSets.Count.ShouldBe(_groupCount);
                return(Task.CompletedTask);
            });

            var block = _parallelTestHelper.GenerateBlock(chain.BestChainHash, chain.BestChainHeight, transactions);

            block = (await _blockExecutingService.ExecuteBlockAsync(block.Header, transactions)).Block;
            block.TransactionIds.Count().ShouldBe(_transactionCount + 1);

            var transactionResults = await GetTransactionResultsAsync(block.Body.TransactionIds.ToList(), block.Header);

            transactionResults.Count(t => t.Status == TransactionResultStatus.Mined).ShouldBe(_groupCount);
            transactionResults.Count(t => t.Status == TransactionResultStatus.Conflict).ShouldBe(_groupCount + 1);
            await _blockchainService.AddBlockAsync(block);

            await _blockAttachService.AttachBlockAsync(block);

            var accountAddress = await _accountService.GetAccountAsync();

            var chainContext = new ChainContext
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Height
            };
            var tokenContractAddress =
                await _smartContractAddressService.GetAddressByContractNameAsync(chainContext, TokenSmartContractAddressNameProvider.StringName);

            var nonparallelContractCode =
                await _nonparallelContractCodeProvider.GetNonparallelContractCodeAsync(chainContext,
                                                                                       tokenContractAddress);

            nonparallelContractCode.ShouldBeNull();

            foreach (var transaction in transactions)
            {
                if (transaction.To == tokenContractAddress)
                {
                    continue;
                }
                var param = IncreaseWinMoneyInput.Parser.ParseFrom(transaction.Params);
                var input = new QueryTwoUserWinMoneyInput
                {
                    First  = param.First,
                    Second = param.Second
                };
                var queryTransaction = _parallelTestHelper.GenerateTransaction(accountAddress,
                                                                               ParallelTestHelper.BasicFunctionWithParallelContractAddress,
                                                                               nameof(BasicFunctionWithParallelContract.QueryTwoUserWinMoney), input);
                var byteString = await _parallelTestHelper.ExecuteReadOnlyAsync(queryTransaction, block.GetHash(), block.Height);

                var output = TwoUserMoneyOut.Parser.ParseFrom(byteString);
                output.FirstInt64Value.ShouldBe(1);
                var result = transactionResults.First(t => t.TransactionId == transaction.GetHash());
                if (result.Status == TransactionResultStatus.Mined)
                {
                    output.SecondInt64Value.ShouldBe(1);
                }
                else if (result.Status == TransactionResultStatus.Conflict)
                {
                    output.SecondInt64Value.ShouldBe(0);
                }
            }

            nonparallelContractCode =
                await _nonparallelContractCodeProvider.GetNonparallelContractCodeAsync(new ChainContext
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Height
            }, ParallelTestHelper.BasicFunctionWithParallelContractAddress);

            nonparallelContractCode.CodeHash.ShouldBe(HashHelper.ComputeFrom(_parallelTestHelper.BasicFunctionWithParallelContractCode));

            var blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(block.GetHash());

            blockStateSet.Changes.Count.ShouldBeGreaterThan(0);
            var blockExecutedData = blockStateSet.BlockExecutedData.First();
            var versionedState    = await _versionedStates.GetAsync(blockExecutedData.Key);

            versionedState.ShouldBeNull();

            await _blockchainStateService.MergeBlockStateAsync(block.Height, block.GetHash());

            blockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(block.GetHash());

            blockStateSet.ShouldBeNull();

            nonparallelContractCode =
                await _nonparallelContractCodeProvider.GetNonparallelContractCodeAsync(new ChainContext
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Height
            }, ParallelTestHelper.BasicFunctionWithParallelContractAddress);

            nonparallelContractCode.CodeHash.ShouldBe(HashHelper.ComputeFrom(_parallelTestHelper.BasicFunctionWithParallelContractCode));

            versionedState = await _versionedStates.GetAsync(blockExecutedData.Key);

            versionedState.Key.ShouldBe(blockExecutedData.Key);
            versionedState.Value.ShouldBe(blockExecutedData.Value);

            groupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = block.GetHash(), BlockHeight = block.Height },
                transactions);

            groupedTransactions.Parallelizables.Count.ShouldBe(1);
            groupedTransactions.Parallelizables[0][0].To.ShouldBe(tokenContractAddress);
            groupedTransactions.NonParallelizables.Count.ShouldBe(_transactionCount);

            otherGroupedTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = block.GetHash(), BlockHeight = block.Height },
                otherTransactions);

            otherGroupedTransactions.Parallelizables.Count.ShouldBe(1);
            otherGroupedTransactions.Parallelizables[0][0].To.ShouldBe(tokenContractAddress);
            otherGroupedTransactions.NonParallelizables.Count.ShouldBe(_transactionCount);

            groupedTransferTransactions = await _grouper.GroupAsync(
                new ChainContext { BlockHash = chain.BestChainHash, BlockHeight = chain.BestChainHeight },
                transferTransactions);

            groupedTransferTransactions.Parallelizables.Count.ShouldBe(1);
            groupedTransferTransactions.Parallelizables[0].Count.ShouldBe(transferTransactions.Count);
            groupedTransferTransactions.NonParallelizables.Count.ShouldBe(0);

            poolSize = (await _txHub.GetTransactionPoolStatusAsync()).AllTransactionCount;

            poolSize.ShouldBe(transactions.Count * 2 + transferTransactions.Count - block.TransactionIds.Count());
        }
        public async Task BlockExecutedData_Test()
        {
            var chain = await _blockchainService.GetChainAsync();

            var blockStateSet = new BlockStateSet
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight,
            };
            await _blockStateSetManger.SetBlockStateSetAsync(blockStateSet);

            var transactionDic = new Dictionary <string, Transaction>();

            for (int i = 0; i < 5; i++)
            {
                var transaction = new Transaction
                {
                    From           = SampleAddress.AddressList[i],
                    To             = SampleAddress.AddressList[i + 1],
                    RefBlockNumber = chain.BestChainHeight - 1,
                    MethodName     = "Test"
                };
                transactionDic.Add(
                    string.Join("/", KernelConstants.BlockExecutedDataKey, nameof(Transaction),
                                transaction.GetHash().ToString()), transaction);
            }

            await _blockchainExecutedDataService.AddBlockExecutedDataAsync(chain.BestChainHash,
                                                                           transactionDic);

            var transactionResult = new TransactionResult
            {
                TransactionId = transactionDic.First().Value.GetHash()
            };
            var transactionResultKey = string.Join("/", KernelConstants.BlockExecutedDataKey,
                                                   nameof(TransactionResult), transactionResult.TransactionId.ToString());
            await _blockchainExecutedDataService.AddBlockExecutedDataAsync(chain.BestChainHash, transactionResultKey,
                                                                           transactionResult);

            var chainKey = string.Join("/", KernelConstants.BlockExecutedDataKey, nameof(Chain));
            await _blockchainExecutedDataService.AddBlockExecutedDataAsync(chain.BestChainHash, chainKey, chain);

            var newBlockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            newBlockStateSet.BlockHash.ShouldBe(blockStateSet.BlockHash);
            newBlockStateSet.BlockHeight.ShouldBe(blockStateSet.BlockHeight);
            newBlockStateSet.BlockExecutedData.Count.ShouldBe(7);
            newBlockStateSet.BlockExecutedData.Keys.ShouldContain(key => key.Contains(typeof(Transaction).Name));
            newBlockStateSet.BlockExecutedData.Keys.ShouldContain(key => key.Contains(typeof(TransactionResult).Name));
            newBlockStateSet.BlockExecutedData.Keys.ShouldContain(key => key.Contains(typeof(Chain).Name));

            var chainContext = new ChainContext
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };
            var chainFromBlockExecutedData =
                await _blockchainExecutedDataService.GetBlockExecutedDataAsync <Chain>(chainContext, chainKey);

            chainFromBlockExecutedData.ShouldBe(chain);

            var transactionResultFromBlockExecutedData =
                await _blockchainExecutedDataService.GetBlockExecutedDataAsync <TransactionResult>(chainContext,
                                                                                                   transactionResultKey);

            transactionResultFromBlockExecutedData.ShouldBe(transactionResult);
            foreach (var keyPair in transactionDic)
            {
                var transaction =
                    await _blockchainExecutedDataService.GetBlockExecutedDataAsync <Transaction>(chainContext, keyPair.Key);

                transaction.ShouldBe(keyPair.Value);
            }
        }
        public async Task BlockExecutedData_Test()
        {
            var genesisBlock = _kernelTestHelper.GenerateBlock(0, Hash.Empty, new List <Transaction>());
            var chain        = await _blockchainService.CreateChainAsync(genesisBlock, new List <Transaction>());

            var blockStateSet = new BlockStateSet
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            };
            await _blockStateSetManger.SetBlockStateSetAsync(blockStateSet);

            var transactionDic = new Dictionary <string, Transaction>();

            for (var i = 0; i < 5; i++)
            {
                var transaction = new Transaction
                {
                    From           = SampleAddress.AddressList[i],
                    To             = SampleAddress.AddressList[i + 1],
                    RefBlockNumber = chain.BestChainHeight - 1,
                    MethodName     = "Test"
                };
                transactionDic.Add(GetBlockExecutedDataKey <Transaction>(transaction.GetHash()), transaction);
            }

            await _transactionBlockchainExecutedDataService.AddBlockExecutedDataAsync(new BlockIndex
            {
                BlockHash   = blockStateSet.BlockHash,
                BlockHeight = blockStateSet.BlockHeight
            }, transactionDic);

            var transactionResult = new TransactionResult
            {
                TransactionId = transactionDic.First().Value.GetHash()
            };
            var transactionResultKey = GetBlockExecutedDataKey <TransactionResult>(transactionResult.TransactionId);
            await _transactionResultBlockchainExecutedDataService.AddBlockExecutedDataAsync(new BlockIndex
            {
                BlockHash   = chain.BestChainHash,
                BlockHeight = chain.BestChainHeight
            },
                                                                                            transactionResultKey,
                                                                                            transactionResult);

            var chainKey = GetBlockExecutedDataKey <Chain>();
            await _chainBlockchainExecutedDataService.AddBlockExecutedDataAsync(new BlockIndex
            {
                BlockHash   = blockStateSet.BlockHash,
                BlockHeight = blockStateSet.BlockHeight
            },
                                                                                chainKey, chain);

            var newBlockStateSet = await _blockStateSetManger.GetBlockStateSetAsync(chain.BestChainHash);

            newBlockStateSet.BlockHash.ShouldBe(blockStateSet.BlockHash);
            newBlockStateSet.BlockHeight.ShouldBe(blockStateSet.BlockHeight);
            newBlockStateSet.BlockExecutedData.Count.ShouldBe(7);
            newBlockStateSet.BlockExecutedData.Keys.ShouldContain(key => key.Contains(typeof(Transaction).Name));
            newBlockStateSet.BlockExecutedData.Keys.ShouldContain(key => key.Contains(typeof(TransactionResult).Name));
            newBlockStateSet.BlockExecutedData.Keys.ShouldContain(key => key.Contains(typeof(Chain).Name));

            blockStateSet = await AddBlockStateSetAsync(blockStateSet);

            CheckBlockExecutedData(blockStateSet, chain, transactionResult, transactionDic);
            await _blockchainStateService.MergeBlockStateAsync(chain.BestChainHeight, chain.BestChainHash);

            CheckBlockExecutedData(blockStateSet, chain, transactionResult, transactionDic);

            blockStateSet = await AddBlockStateSetAsync(blockStateSet);

            CheckBlockExecutedData(blockStateSet, chain, transactionResult, transactionDic);
        }