public async Task BlockState_MergeBlock_Normal()
        {
            var blockStateSet1 = new BlockStateSet()
            {
                BlockHeight  = 1,
                BlockHash    = Hash.Generate(),
                PreviousHash = Hash.Empty
            };
            var blockStateSet2 = new BlockStateSet()
            {
                BlockHeight  = 2,
                BlockHash    = Hash.Generate(),
                PreviousHash = blockStateSet1.BlockHash
            };
            var blockStateSet3 = new BlockStateSet()
            {
                BlockHeight  = 3,
                BlockHash    = Hash.Generate(),
                PreviousHash = blockStateSet2.BlockHash
            };

            //test merge block height 1
            {
                await _blockchainStateManager.SetBlockStateSetAsync(blockStateSet1);

                await _blockchainStateMergingService.MergeBlockStateAsync(blockStateSet1.BlockHeight,
                                                                          blockStateSet1.BlockHash);

                var chainStateInfo = await _blockchainStateManager.GetChainStateInfoAsync();

                chainStateInfo.BlockHeight.ShouldBe(1);
                chainStateInfo.BlockHash.ShouldBe(blockStateSet1.BlockHash);
            }

            //test merge block height 2
            {
                await _blockchainStateManager.SetBlockStateSetAsync(blockStateSet2);

                await _blockchainStateMergingService.MergeBlockStateAsync(blockStateSet2.BlockHeight,
                                                                          blockStateSet2.BlockHash);

                var chainStateInfo = await _blockchainStateManager.GetChainStateInfoAsync();

                chainStateInfo.BlockHeight.ShouldBe(2);
                chainStateInfo.BlockHash.ShouldBe(blockStateSet2.BlockHash);
            }

            //test merge height 3 without block state set before
            {
                await Should.ThrowAsync <InvalidOperationException>(() => _blockchainStateMergingService.MergeBlockStateAsync(blockStateSet3.BlockHeight,
                                                                                                                              blockStateSet3.BlockHash));

                var chainStateInfo = await _blockchainStateManager.GetChainStateInfoAsync();

                chainStateInfo.BlockHeight.ShouldBe(2);
                chainStateInfo.BlockHash.ShouldBe(blockStateSet2.BlockHash);
            }
        }
Exemple #2
0
        public async Task IterationCleanup()
        {
            await _chainStateInfoCollection.SetAsync(_chain.Id.ToStorageKey(), _chainStateInfo);

            foreach (var blockStateSet in _blockStateSets)
            {
                await _blockchainStateManager.SetBlockStateSetAsync(blockStateSet);
            }
        }
Exemple #3
0
        public async Task <Block> FillBlockAfterExecutionAsync(BlockHeader blockHeader, List <Transaction> transactions,
                                                               List <ExecutionReturnSet> blockExecutionReturnSet)
        {
            var bloom         = new Bloom();
            var blockStateSet = new BlockStateSet
            {
                BlockHeight  = blockHeader.Height,
                PreviousHash = blockHeader.PreviousBlockHash
            };

            foreach (var returnSet in blockExecutionReturnSet)
            {
                foreach (var change in returnSet.StateChanges)
                {
                    blockStateSet.Changes[change.Key] = change.Value;
                }

                if (returnSet.Status == TransactionResultStatus.Mined)
                {
                    bloom.Combine(new[] { new Bloom(returnSet.Bloom.ToByteArray()) });
                }
            }

            blockHeader.Bloom = ByteString.CopyFrom(bloom.Data);
            var merkleTreeRootOfWorldState = ComputeHash(GetDeterministicByteArrays(blockStateSet));

            blockHeader.MerkleTreeRootOfWorldState = merkleTreeRootOfWorldState;

            var allExecutedTransactionIds = transactions.Select(x => x.GetHash()).ToList();
            var bmt = new BinaryMerkleTree();

            bmt.AddNodes(allExecutedTransactionIds);
            blockHeader.MerkleTreeRootOfTransactions = bmt.ComputeRootHash();

            _blockExtraDataService.FillMerkleTreeRootExtraDataForTransactionStatus(blockHeader,
                                                                                   blockExecutionReturnSet.Select(executionReturn =>
                                                                                                                  (executionReturn.TransactionId, executionReturn.Status)));

            var blockBody = new BlockBody();

            blockBody.Transactions.AddRange(allExecutedTransactionIds);
            blockBody.TransactionList.AddRange(transactions);

            var block = new Block
            {
                Header = blockHeader,
                Body   = blockBody
            };

            blockBody.BlockHeader   = blockHeader.GetHash();
            blockStateSet.BlockHash = blockHeader.GetHash();

            await _blockchainStateManager.SetBlockStateSetAsync(blockStateSet);

            return(block);
        }
        public async Task <Block> FillBlockAfterExecutionAsync(BlockHeader blockHeader, List <Transaction> transactions,
                                                               List <ExecutionReturnSet> blockExecutionReturnSet)
        {
            var bloom         = new Bloom();
            var blockStateSet = new BlockStateSet
            {
                BlockHeight  = blockHeader.Height,
                PreviousHash = blockHeader.PreviousBlockHash
            };

            foreach (var returnSet in blockExecutionReturnSet)
            {
                foreach (var change in returnSet.StateChanges)
                {
                    blockStateSet.Changes[change.Key] = change.Value;
                }

                if (returnSet.Status == TransactionResultStatus.Mined)
                {
                    bloom.Combine(new[] { new Bloom(returnSet.Bloom.ToByteArray()) });
                }
            }

            blockHeader.Bloom = ByteString.CopyFrom(bloom.Data);
            blockHeader.MerkleTreeRootOfWorldState        = CalculateWorldStateMerkleTreeRoot(blockStateSet);
            blockHeader.MerkleTreeRootOfTransactionStatus =
                CalculateTransactionStatusMerkleTreeRoot(blockExecutionReturnSet);

            var allExecutedTransactionIds = transactions.Select(x => x.GetHash()).ToList();

            blockHeader.MerkleTreeRootOfTransactions = CalculateTransactionMerkleTreeRoot(allExecutedTransactionIds);

            var blockHash = blockHeader.GetHashWithoutCache();
            var blockBody = new BlockBody
            {
                BlockHeader = blockHash
            };

            blockBody.TransactionIds.AddRange(allExecutedTransactionIds);

            var block = new Block
            {
                Header = blockHeader,
                Body   = blockBody
            };

            blockBody.BlockHeader   = blockHash;
            blockStateSet.BlockHash = blockHash;

            await _blockchainStateManager.SetBlockStateSetAsync(blockStateSet);

            return(block);
        }
 public async Task SetBlockStateSetAsync(BlockStateSet blockStateSet)
 {
     await _blockchainStateManager.SetBlockStateSetAsync(blockStateSet);
 }