private Task <Block> FillBlockAfterExecutionAsync(BlockHeader header,
                                                          IEnumerable <Transaction> transactions, ExecutionReturnSetCollection executionReturnSetCollection, BlockStateSet blockStateSet)
        {
            Logger.LogTrace("Start block field filling after execution.");
            var bloom = new Bloom();

            foreach (var returnSet in executionReturnSetCollection.Executed)
            {
                bloom.Combine(new[] { new Bloom(returnSet.Bloom.ToByteArray()) });
            }

            var allExecutedTransactionIds = transactions.Select(x => x.GetHash()).ToList();
            var orderedReturnSets         = executionReturnSetCollection.GetExecutionReturnSetList()
                                            .OrderBy(d => allExecutedTransactionIds.IndexOf(d.TransactionId)).ToList();

            var block = new Block
            {
                Header = new BlockHeader(header)
                {
                    Bloom = ByteString.CopyFrom(bloom.Data),
                    MerkleTreeRootOfWorldState        = CalculateWorldStateMerkleTreeRoot(blockStateSet),
                    MerkleTreeRootOfTransactionStatus = CalculateTransactionStatusMerkleTreeRoot(orderedReturnSets),
                    MerkleTreeRootOfTransactions      = CalculateTransactionMerkleTreeRoot(allExecutedTransactionIds)
                },
                Body = new BlockBody
                {
                    TransactionIds = { allExecutedTransactionIds }
                }
            };

            Logger.LogTrace("Finish block field filling after execution.");
            return(Task.FromResult(block));
        }
        protected virtual async Task <Block> FillBlockAfterExecutionAsync(BlockHeader blockHeader, List <Transaction> transactions,
                                                                          ReturnSetCollection returnSetCollection)
        {
            Logger.LogTrace("Start block field filling after execution.");
            var bloom         = new Bloom();
            var blockStateSet = new BlockStateSet
            {
                BlockHeight  = blockHeader.Height,
                PreviousHash = blockHeader.PreviousBlockHash
            };

            foreach (var returnSet in returnSetCollection.Executed)
            {
                foreach (var change in returnSet.StateChanges)
                {
                    blockStateSet.Changes[change.Key] = change.Value;
                    blockStateSet.Deletes.Remove(change.Key);
                }

                foreach (var delete in returnSet.StateDeletes)
                {
                    blockStateSet.Deletes.AddIfNotContains(delete.Key);
                    blockStateSet.Changes.Remove(delete.Key);
                }

                bloom.Combine(new[] { new Bloom(returnSet.Bloom.ToByteArray()) });
            }

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

            var allExecutedTransactionIds = transactions.Select(x => x.GetHash()).ToList();
            var orderedReturnSets         = returnSetCollection.ToList().AsParallel()
                                            .OrderBy(d => allExecutedTransactionIds.IndexOf(d.TransactionId)).ToList();

            blockHeader.MerkleTreeRootOfTransactionStatus =
                CalculateTransactionStatusMerkleTreeRoot(orderedReturnSets);

            blockHeader.MerkleTreeRootOfTransactions = CalculateTransactionMerkleTreeRoot(allExecutedTransactionIds);

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

            blockBody.TransactionIds.AddRange(allExecutedTransactionIds);

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

            blockStateSet.BlockHash = blockHash;
            Logger.LogTrace("Set block state set.");

            await _blockchainStateService.SetBlockStateSetAsync(blockStateSet);

            Logger.LogTrace("Finish block field filling after execution.");
            return(block);
        }
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);
        }
Exemple #4
0
        public void Combine_Test()
        {
            var bloom      = new Bloom();
            var byteString = ByteString.CopyFrom(new Bloom().Data);

            bloom.Combine(new[] { new Bloom(byteString.ToByteArray()) });
            bloom.Data.Length.ShouldBe(0);
            var newBloom = new Bloom();

            newBloom.AddValue(new StringValue()
            {
                Value = "ELF"
            });
            bloom.Combine(new[]
            {
                newBloom
            });
            bloom.Data.Length.ShouldBe(256);
        }
        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 Validate_EmptyHeader_WithIndexedData_Test()
        {
            var block = _kernelTestHelper.GenerateBlock(10, Hash.Empty);
            var bloom = new Bloom();

            bloom.Combine(new [] {
                GetSideChainBlockDataIndexedEventBloom(), GetParentChainBlockDataIndexedEventBloom()
            });
            block.Header.Bloom = ByteString.CopyFrom(bloom.Data);

            var res = await _crossChainBlockValidationProvider.ValidateBlockAfterExecuteAsync(block);

            Assert.False(res);
        }
Exemple #7
0
        private BlockExecutedSet GenerateBlockExecutedSet(long blockHeight, List <LogEvent> logEvents)
        {
            var blockExecutedSet = new BlockExecutedSet();
            var transactions     = new List <Transaction>();

            for (var i = 0; i < logEvents.Count + 1; i++)
            {
                transactions.Add(_kernelTestHelper.GenerateTransaction());
            }

            var block = _kernelTestHelper.GenerateBlock(blockHeight - 1, HashHelper.ComputeFrom("PreviousBlockHash"),
                                                        transactions);

            blockExecutedSet.Block = block;
            blockExecutedSet.TransactionResultMap = new Dictionary <Hash, TransactionResult>
            {
                {
                    transactions[0].GetHash(),
                    new TransactionResult {
                        TransactionId = transactions[0].GetHash(), Bloom = ByteString.Empty
                    }
                }
            };

            var bloom   = new Bloom();
            var logs    = new List <LogEvent>();
            var txIndex = 1;

            foreach (var logEvent in logEvents)
            {
                bloom.Combine(new List <Bloom> {
                    logEvent.GetBloom()
                });
                logs.Add(logEvent);

                var transactionResult = new TransactionResult
                {
                    TransactionId = transactions[txIndex].GetHash(),
                    Bloom         = ByteString.CopyFrom(bloom.Data),
                };
                transactionResult.Logs.AddRange(logs);

                blockExecutedSet.TransactionResultMap.Add(transactions[txIndex].GetHash(), transactionResult);
                txIndex++;
            }

            block.Header.Bloom = ByteString.CopyFrom(bloom.Data);

            return(blockExecutedSet);
        }
Exemple #8
0
        public async Task Validate_EmptyHeader_WithIndexedData_Test()
        {
            var fakeMerkleTreeRoot1    = Hash.FromString("fakeMerkleTreeRoot1");
            var fakeSideChainId        = ChainHelper.ConvertBase58ToChainId("2112");
            var fakeSideChainBlockData = CreateSideChainBlockData(fakeSideChainId, 1, fakeMerkleTreeRoot1);

            CreateFakeCacheAndStateData(fakeSideChainId, fakeSideChainBlockData, 2);
            var block = _kernelTestHelper.GenerateBlock(1, Hash.Empty);
            var bloom = new Bloom();

            bloom.Combine(new [] {
                GetSideChainBlockDataIndexedEventBloom(), GetParentChainBlockDataIndexedEventBloom()
            });
            block.Header.Bloom = ByteString.CopyFrom(bloom.Data);

            var res = await _crossChainBlockValidationProvider.ValidateBlockAfterExecuteAsync(block);

            Assert.False(res);
        }