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); } }
public async Task IterationCleanup() { await _chainStateInfoCollection.SetAsync(_chain.Id.ToStorageKey(), _chainStateInfo); foreach (var blockStateSet in _blockStateSets) { await _blockchainStateManager.SetBlockStateSetAsync(blockStateSet); } }
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); }