Beispiel #1
0
        private IEnumerable <(long, MerklePath)> GetEnumerableMerklePath(IList <SideChainBlockData> indexedSideChainBlockDataResult,
                                                                         int sideChainId)
        {
            var binaryMerkleTree = new BinaryMerkleTree();

            foreach (var blockInfo in indexedSideChainBlockDataResult)
            {
                binaryMerkleTree.AddNode(blockInfo.TransactionMerkleTreeRoot);
            }

            binaryMerkleTree.ComputeRootHash();
            // This is to tell side chain the merkle path for one side chain block,
            // which could be removed with subsequent improvement.
            // This assumes indexing multi blocks from one chain at once, actually only one block every time right now.
            var merklepathList = new List <(long, MerklePath)>();

            for (var i = 0; i < indexedSideChainBlockDataResult.Count; i++)
            {
                var info = indexedSideChainBlockDataResult[i];
                if (!info.ChainId.Equals(sideChainId))
                {
                    continue;
                }
                var merklePath = binaryMerkleTree.GenerateMerklePath(i);
                merklepathList.Add((info.Height, merklePath));
            }
            //Logger.LogTrace($"Got merkle path list size {merklepathList.Count}");
            return(merklepathList);
        }
        public void MultiNodesTest()
        {
            var tree1 = BinaryMerkleTree.FromLeafNodes(CreateLeaves(new[] { "a", "e" }));

            //See if the hash of merkle tree is equal to the element’s hash.
            var root1 = tree1.Root;

            Assert.Equal(GetHashFromStrings("a", "e"), root1);

            var  tree2 = BinaryMerkleTree.FromLeafNodes(CreateLeaves(new[] { "a", "e", "l" }));
            var  root2 = tree2.Root;
            Hash right = GetHashFromStrings("l", "l");

            Assert.Equal(HashHelper.ConcatAndCompute(root1, right), root2);

            var  tree3  = BinaryMerkleTree.FromLeafNodes(CreateLeaves(new[] { "a", "e", "l", "f" }));
            var  root3  = tree3.Root;
            Hash right2 = GetHashFromStrings("l", "f");

            Assert.Equal(HashHelper.ConcatAndCompute(root1, right2), root3);

            var  tree4 = BinaryMerkleTree.FromLeafNodes(CreateLeaves(new[] { "a", "e", "l", "f", "a" }));
            var  root4 = tree4.Root;
            Hash l2    = GetHashFromStrings("a", "a");
            Hash l3    = HashHelper.ConcatAndCompute(l2, l2);

            Assert.Equal(HashHelper.ConcatAndCompute(root3, l3), root4);
        }
Beispiel #3
0
        private Hash ComputeRootHash(IEnumerable <SideChainBlockData> blockInfo)
        {
            var binaryMerkleTree = BinaryMerkleTree.FromLeafNodes(blockInfo.Select(sideChainBlockData =>
                                                                                   sideChainBlockData.TransactionStatusMerkleTreeRoot));

            return(binaryMerkleTree.Root);
        }
Beispiel #4
0
        public async Task PrepareExtraDataForNextMiningAsync_Test()
        {
            var sideChainId             = 123;
            var sideChainBlockInfoCache = new List <SideChainBlockData>();
            var cachingCount            = 5;

            for (int i = 0; i < cachingCount + CrossChainConstants.DefaultBlockCacheEntityCount; i++)
            {
                sideChainBlockInfoCache.Add(new SideChainBlockData()
                {
                    ChainId = sideChainId,
                    Height  = (i + 1),
                    TransactionStatusMerkleTreeRoot = HashHelper.ComputeFrom((sideChainId + 1).ToString())
                });
            }

            var crossChainBlockData = new CrossChainBlockData
            {
                SideChainBlockDataList = { sideChainBlockInfoCache }
            };

            _crossChainTestHelper.AddFakePendingCrossChainIndexingProposal(sideChainId,
                                                                           CreatePendingChainIndexingProposalStatus(SampleAddress.AddressList[0],
                                                                                                                    HashHelper.ComputeFrom("ProposalId"), crossChainBlockData)
                                                                           );

            var res = await _crossChainIndexingDataService.PrepareExtraDataForNextMiningAsync(Hash.Empty, 1);

            var crossChainExtraData    = CrossChainExtraData.Parser.ParseFrom(res);
            var expectedMerkleTreeRoot = BinaryMerkleTree
                                         .FromLeafNodes(sideChainBlockInfoCache.Select(s => s.TransactionStatusMerkleTreeRoot)).Root;

            Assert.Equal(expectedMerkleTreeRoot, crossChainExtraData.TransactionStatusMerkleTreeRoot);
            Assert.Equal(res, crossChainBlockData.ExtractCrossChainExtraDataFromCrossChainBlockData());
        }
Beispiel #5
0
        private Hash ComputeRootWithMultiHash(IEnumerable <Hash> nodes)
        {
            var binaryMerkleTree = new BinaryMerkleTree();

            binaryMerkleTree.AddNodes(nodes);
            return(binaryMerkleTree.ComputeRootHash());
        }
        public void MerklePathTest2LeafNodes()
        {
            var hashes = CreateLeaves(new[] { "a", "e" });
            var tree   = BinaryMerkleTree.FromLeafNodes(hashes);

            // test invalid index
            Assert.Throws <InvalidOperationException>(() => tree.GenerateMerklePath(2));

            // test "a"
            var path = tree.GenerateMerklePath(0);

            Assert.NotNull(path);
            Assert.True(1 == path.MerklePathNodes.Count);
            var realPath1 = GenerateMerklePath(new[] { 1 }, tree.Nodes);

            Assert.Equal(realPath1, path);

            // test "e"
            path = tree.GenerateMerklePath(1);
            Assert.NotNull(path);
            Assert.True(1 == path.MerklePathNodes.Count);
            var realPath2 = GenerateMerklePath(new[] { 0 }, tree.Nodes);

            Assert.Equal(realPath2, path);
        }
Beispiel #7
0
        public async Task Execute_Block_NonCancellable()
        {
            var blockHeader = new BlockHeader
            {
                Height            = 2,
                PreviousBlockHash = Hash.Empty,
                Time = DateTime.UtcNow.ToTimestamp()
            };
            var txs = BuildTransactions(5);

            var block = await _blockExecutingService.ExecuteBlockAsync(blockHeader, txs);

            var allTxIds = txs.Select(x => x.GetHash()).ToList();

            block.Body.TransactionsCount.ShouldBe(txs.Count);

            var binaryMerkleTree = new BinaryMerkleTree();

            binaryMerkleTree.AddNodes(allTxIds);
            var merkleTreeRoot = binaryMerkleTree.ComputeRootHash();

            block.Header.MerkleTreeRootOfTransactions.ShouldBe(merkleTreeRoot);

            block.Body.Transactions.ShouldBe(allTxIds);
            block.Body.TransactionList.ShouldBe(txs);
        }
        public async Task <ByteString> GetExtraDataForFillingBlockHeaderAsync(BlockHeader blockHeader)
        {
            if (blockHeader.Height == Constants.GenesisBlockHeight)
            {
                return(ByteString.Empty);
            }

            var newCrossChainBlockData =
                await _crossChainIndexingDataService.GetCrossChainBlockDataForNextMiningAsync(blockHeader.PreviousBlockHash,
                                                                                              blockHeader.Height - 1);

            if (newCrossChainBlockData == null || newCrossChainBlockData.SideChainBlockData.Count == 0)
            {
                return(ByteString.Empty);
            }

            var txRootHashList = newCrossChainBlockData.SideChainBlockData.Select(scb => scb.TransactionStatusMerkleTreeRoot).ToList();
            var calculatedSideChainTransactionsRoot = BinaryMerkleTree.FromLeafNodes(txRootHashList).Root;

            Logger.LogTrace("Cross chain extra data generated.");
            return(new CrossChainExtraData {
                TransactionStatusMerkleTreeRoot = calculatedSideChainTransactionsRoot
            }
                   .ToByteString());
        }
        public void MerkleProofTest_MultiLeaves()
        {
            string hex1  = "5a7d71da020cae179a0dfe82bd3c967e1573377578f4cc87bc21f74f2556c0ef";
            var    hash1 = CreateLeafFromHex(hex1);

            string hex2  = "a28bf94d0491a234d1e99abc62ed344eb55bb11aeecacc35c1b75bfa85c8983f";
            var    hash2 = CreateLeafFromHex(hex2);

            string hex3  = "bf6ae8809d017f07b27ad1620839c6503666fb55f7fe7ac70881e8864ce5a3ff";
            var    hash3 = CreateLeafFromHex(hex3);

            string hex4  = "bac4adcf8066921237320cdcddb721f5ba5d34065b9c54fe7f9893d8dfe52f17";
            var    hash4 = CreateLeafFromHex(hex4);

            string hex5  = "bac4adcf8066921237320cdcddb721f5ba5d34065b9c54fe7f9893d8dfe52f17";
            var    hash5 = CreateLeafFromHex(hex5);
            var    tree  = BinaryMerkleTree.FromLeafNodes(new[] { hash1, hash2, hash3, hash4, hash5 });

            //See if the hash of merkle tree is equal to the element’s hash.
            var root           = tree.Root;
            var path           = tree.GenerateMerklePath(4);
            var calculatedRoot = path.ComputeRootWithLeafNode(hash5);

            //Assert.Contains(hash3, path.Path);
            Assert.Equal(root, calculatedRoot);
        }
Beispiel #10
0
        public void MerklePathTest2LeafNodes()
        {
            var hashes = CreateLeaves(new[] { "a", "e" });
            var tree   = new BinaryMerkleTree();

            tree.AddNodes(hashes);
            var path = tree.GenerateMerklePath(0);

            Assert.Null(path);
            tree.ComputeRootHash();
            // test invalid index
            path = tree.GenerateMerklePath(2);
            Assert.Null(path);

            // test "a"
            path = tree.GenerateMerklePath(0);
            Assert.NotNull(path);
            Assert.True(1 == path.Path.Count);
            var realPath = new List <Hash> {
                tree.Nodes[1]
            };

            Assert.Equal(realPath, path.Path.ToList());

            // test "e"
            path = tree.GenerateMerklePath(1);
            Assert.NotNull(path);
            Assert.True(1 == path.Path.Count);
            realPath = new List <Hash> {
                tree.Nodes[0]
            };
            Assert.Equal(realPath, path.Path.ToList());
        }
        public async Task CrossChain_Verification()
        {
            int  parentChainId = 123;
            long lockedToken   = 10;
            var  sideChainId   = await InitAndCreateSideChain(parentChainId, lockedToken);

            var txId             = Hash.FromString("sideChainBlockHash");
            var binaryMerkleTree = new BinaryMerkleTree();
            var fakeHash1        = Hash.FromString("fake1");
            var fakeHash2        = Hash.FromString("fake2");

            var rawBytes = txId.DumpByteArray().Concat(EncodingHelper.GetBytesFromUtf8String(TransactionResultStatus.Mined.ToString()))
                           .ToArray();
            var hash = Hash.FromRawBytes(rawBytes);

            binaryMerkleTree.AddNodes(new[] { hash, fakeHash1, fakeHash2 });
            var  merkleTreeRoot    = binaryMerkleTree.ComputeRootHash();
            var  merklePath        = binaryMerkleTree.GenerateMerklePath(0);
            var  parentChainHeight = 1;
            Hash fakeTransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot");
            var  parentChainBlockData            = new ParentChainBlockData
            {
                Root = new ParentChainBlockRootInfo
                {
                    ParentChainHeight   = parentChainHeight,
                    ParentChainId       = parentChainId,
                    CrossChainExtraData = new CrossChainExtraData
                    {
                        SideChainTransactionsRoot = merkleTreeRoot
                    },
                    TransactionStatusMerkleRoot = fakeTransactionStatusMerkleRoot
                }
            };
            var crossChainBlockData = new CrossChainBlockData
            {
                ParentChainBlockData = { parentChainBlockData }
            };

            var indexingTx = await GenerateTransactionAsync(CrossChainContractAddress,
                                                            CrossChainConstants.CrossChainIndexingMethodName, null, crossChainBlockData);

            var block = await MineAsync(new List <Transaction> {
                indexingTx
            });

            var verificationInput = new VerifyTransactionInput()
            {
                TransactionId     = txId,
                ParentChainHeight = parentChainHeight
            };

            verificationInput.Path.AddRange(merklePath.Path);
            var txRes = await ExecuteContractWithMiningAsync(
                CrossChainContractAddress,
                nameof(CrossChainContract.VerifyTransaction), verificationInput);

            var verified = BoolValue.Parser.ParseFrom(txRes.ReturnValue).Value;

            Assert.True(verified);
        }
        /// <summary>
        /// Get the merkle path of a transaction.
        /// </summary>
        /// <param name="transactionId"></param>
        /// <returns></returns>
        public async Task <MerklePathDto> GetMerklePathByTransactionIdAsync(string transactionId)
        {
            Hash transactionIdHash;

            try
            {
                transactionIdHash = Hash.LoadFromHex(transactionId);
            }
            catch
            {
                throw new UserFriendlyException(Error.Message[Error.InvalidTransactionId],
                                                Error.InvalidTransactionId.ToString());
            }

            var transactionResult = await GetMinedTransactionResultAsync(transactionIdHash);

            var blockHash = transactionResult.BlockHash;
            var blockInfo = await _blockchainService.GetBlockByHashAsync(blockHash);

            var transactionIds = blockInfo.Body.TransactionIds;
            var index          = transactionIds.IndexOf(transactionIdHash);

            if (index == -1)
            {
                throw new UserFriendlyException(Error.Message[Error.NotFound], Error.NotFound.ToString());
            }
            var leafNodes = await GetLeafNodesAsync(blockInfo.TransactionIds);

            var binaryMerkleTree = BinaryMerkleTree.FromLeafNodes(leafNodes);
            var path             = binaryMerkleTree.GenerateMerklePath(index);
            var merklePath       = _objectMapper.Map <MerklePath, MerklePathDto>(path);

            return(merklePath);
        }
        public async Task <ByteString> GetExtraDataForFillingBlockHeaderAsync(BlockHeader blockHeader)
        {
            if (blockHeader.Height == KernelConstants.GenesisBlockHeight)
            {
                return(ByteString.Empty);
            }

            //Logger.LogTrace($"Get new cross chain data with hash {blockHeader.PreviousBlockHash}, height {blockHeader.Height - 1}");

            var newCrossChainBlockData =
                await _crossChainDataProvider.GetCrossChainBlockDataForNextMiningAsync(blockHeader.PreviousBlockHash,
                                                                                       blockHeader.Height - 1);

            if (newCrossChainBlockData == null || newCrossChainBlockData.SideChainBlockData.Count == 0)
            {
                return(ByteString.Empty);
            }

            var txRootHashList = newCrossChainBlockData.SideChainBlockData.Select(scb => scb.TransactionMerkleTreeRoot);
            var calculatedSideChainTransactionsRoot = new BinaryMerkleTree().AddNodes(txRootHashList).ComputeRootHash();

            return(new CrossChainExtraData {
                SideChainTransactionsRoot = calculatedSideChainTransactionsRoot
            }
                   .ToByteString());
        }
Beispiel #14
0
        public void MerkleProofTest_MultiLeaves()
        {
            var tree = new BinaryMerkleTree();

            string hex1  = "5a7d71da020cae179a0dfe82bd3c967e1573377578f4cc87bc21f74f2556c0ef";
            var    hash1 = CreateLeafFromHex(hex1);

            string hex2  = "a28bf94d0491a234d1e99abc62ed344eb55bb11aeecacc35c1b75bfa85c8983f";
            var    hash2 = CreateLeafFromHex(hex2);

            string hex3  = "bf6ae8809d017f07b27ad1620839c6503666fb55f7fe7ac70881e8864ce5a3ff";
            var    hash3 = CreateLeafFromHex(hex3);

            string hex4  = "bac4adcf8066921237320cdcddb721f5ba5d34065b9c54fe7f9893d8dfe52f17";
            var    hash4 = CreateLeafFromHex(hex4);

            string hex5  = "bac4adcf8066921237320cdcddb721f5ba5d34065b9c54fe7f9893d8dfe52f17";
            var    hash5 = Hash.FromRawBytes(ByteArrayHelpers.FromHexString(hex5)
                                             .Concat(Encoding.UTF8.GetBytes(TransactionResultStatus.Mined.ToString())).ToArray());

            tree.AddNodes(new [] { hash1, hash2, hash3, hash4, hash5 });

            //See if the hash of merkle tree is equal to the element’s hash.
            var root           = tree.ComputeRootHash();
            var path           = tree.GenerateMerklePath(4);
            var calculatedRoot = path.ComputeRootWith(hash5);

            //Assert.Contains(hash3, path.Path);
            Assert.Equal(root, calculatedRoot);
        }
        private Dictionary <long, MerklePath> GetEnumerableMerklePath(IList <SideChainBlockData> indexedSideChainBlockDataResult,
                                                                      int sideChainId)
        {
            var binaryMerkleTree = BinaryMerkleTree.FromLeafNodes(
                indexedSideChainBlockDataResult.Select(sideChainBlockData =>
                                                       sideChainBlockData.TransactionStatusMerkleTreeRoot));

            // This is to tell side chain the merkle path for one side chain block,
            // which could be removed with subsequent improvement.
            var res = new Dictionary <long, MerklePath>();

            for (var i = 0; i < indexedSideChainBlockDataResult.Count; i++)
            {
                var info = indexedSideChainBlockDataResult[i];
                if (!info.ChainId.Equals(sideChainId))
                {
                    continue;
                }

                var merklePath = binaryMerkleTree.GenerateMerklePath(i);
                res.Add(info.Height, merklePath);
            }

            return(res);
        }
Beispiel #16
0
        public async Task Execute_Block_Cancellable()
        {
            var blockHeader       = _kernelTestHelper.GenerateBlock(1, Hash.Empty).Header;
            var nonCancellableTxs = BuildTransactions(5);
            var cancellableTxs    = BuildTransactions(5);
            var cancelToken       = new CancellationTokenSource();

            cancelToken.Cancel();

            var block = await _blockExecutingService.ExecuteBlockAsync(blockHeader, nonCancellableTxs,
                                                                       cancellableTxs, cancelToken.Token);

            var allTxIds = nonCancellableTxs.Select(x => x.GetHash()).ToList();

            allTxIds.Add(cancellableTxs[0].GetHash());
            allTxIds.Add(cancellableTxs[1].GetHash());
            allTxIds.Add(cancellableTxs[2].GetHash());

            var allTxs = new List <Transaction>();

            allTxs.AddRange(nonCancellableTxs);
            allTxs.Add(cancellableTxs[0]);
            allTxs.Add(cancellableTxs[1]);
            allTxs.Add(cancellableTxs[2]);

            block.Body.TransactionsCount.ShouldBe(allTxs.Count);

            var binaryMerkleTree = BinaryMerkleTree.FromLeafNodes(allTxIds);
            var merkleTreeRoot   = binaryMerkleTree.Root;

            block.Header.MerkleTreeRootOfTransactions.ShouldBe(merkleTreeRoot);

            block.Body.TransactionIds.ShouldBe(allTxIds);
        }
Beispiel #17
0
        private bool ValidateBlockExtraDataAsync(CrossChainBlockData crossChainBlockData, CrossChainExtraData extraData)
        {
            var txRootHashList = crossChainBlockData.SideChainBlockData.Select(scb => scb.TransactionStatusMerkleTreeRoot).ToList();
            var calculatedSideChainTransactionsRoot = BinaryMerkleTree.FromLeafNodes(txRootHashList).Root;

            return(calculatedSideChainTransactionsRoot.Equals(extraData.TransactionStatusMerkleTreeRoot));
        }
        public void MerkleNodesCountTest(int leafCount, int expectCount)
        {
            var hashes     = CreateLeaves(leafCount);
            var tree       = BinaryMerkleTree.FromLeafNodes(hashes);
            var nodesCount = tree.Nodes.Count;

            Assert.Equal(expectCount, nodesCount);
        }
Beispiel #19
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 void MerklePathTest(int leafCount, int index)
        {
            var hashes         = CreateLeaves(leafCount);
            var tree           = BinaryMerkleTree.FromLeafNodes(hashes.ToArray());
            var root           = tree.Root;
            var path           = tree.GenerateMerklePath(index);
            var calculatedRoot = path.ComputeRootWithLeafNode(hashes[index]);

            Assert.Equal(root, calculatedRoot);
        }
        public void SingleNodeTest()
        {
            string hex  = "5a7d71da020cae179a0dfe82bd3c967e1573377578f4cc87bc21f74f2556c0ef";
            var    tree = BinaryMerkleTree.FromLeafNodes(new[] { CreateLeafFromHex(hex) });

            //See if the hash of merkle tree is equal to the element’s hash.
            var root     = tree.Root;
            var expected = GetHashFromHexString(hex, hex);

            Assert.Equal(expected, root);
        }
        /// <summary>
        /// Calculate the <see cref="BinaryMerkleTree.Root"/> with path and provided leaf.
        /// </summary>
        /// <param name="merklePath"></param>
        /// <param name="leaf"></param>
        /// <returns></returns>
        public static Hash ComputeRootWith(this MerklePath merklePath, Hash leaf)
        {
            Hash hash = leaf.Clone();

            foreach (var node in merklePath.Path)
            {
                hash = BinaryMerkleTree.CalculateRootFromMultiHash(new[] { hash, node });
            }

            return(hash);
        }
Beispiel #23
0
        private Hash GetHashFromStrings(params string[] strings)
        {
            var hash = Hash.FromString(strings[0]);

            foreach (var s in strings.Skip(1))
            {
                hash = BinaryMerkleTree.CalculateRootFromMultiHash(new [] { hash, Hash.FromString(s) });
            }

            return(hash);
        }
Beispiel #24
0
        public void MerklePathTest(int leaveCount, int index)
        {
            var hashes = CreateLeaves(leaveCount);
            var bmt    = new BinaryMerkleTree();

            bmt.AddNodes(hashes);
            var root           = bmt.ComputeRootHash();
            var path           = bmt.GenerateMerklePath(index);
            var calculatedRoot = path.ComputeRootWith(hashes[index]);

            Assert.Equal(root, calculatedRoot);
        }
        public void MerkleProofTest()
        {
            string hex  = "5a7d71da020cae179a0dfe82bd3c967e1573377578f4cc87bc21f74f2556c0ef";
            var    leaf = CreateLeafFromHex(hex);
            var    tree = BinaryMerkleTree.FromLeafNodes(new[] { leaf });

            //See if the hash of merkle tree is equal to the element’s hash.
            var root           = tree.Root;
            var path           = tree.GenerateMerklePath(0);
            var calculatedRoot = path.ComputeRootWithLeafNode(leaf);

            Assert.Equal(root, calculatedRoot);
        }
Beispiel #26
0
        private Hash CalculateTransactionStatusMerkleTreeRoot(List <ExecutionReturnSet> blockExecutionReturnSet)
        {
            var executionReturnSet = blockExecutionReturnSet.Select(executionReturn =>
                                                                    (executionReturn.TransactionId, executionReturn.Status));
            var nodes = new List <Hash>();

            foreach (var(transactionId, status) in executionReturnSet)
            {
                nodes.Add(GetHashCombiningTransactionAndStatus(transactionId, status));
            }

            return(BinaryMerkleTree.FromLeafNodes(nodes).Root);
        }
        public async Task CrossChain_MerklePath()
        {
            int  parentChainId = 123;
            long lockedToken   = 10;
            long parentChainHeightOfCreation = 10;
            var  sideChainId =
                await InitAndCreateSideChainAsync(parentChainHeightOfCreation, parentChainId, lockedToken);

            var transactionId = Hash.FromString("sideChainBlockHash");

            var fakeHash1 = Hash.FromString("fake1");
            var fakeHash2 = Hash.FromString("fake2");

            var  binaryMerkleTree = BinaryMerkleTree.FromLeafNodes(new[] { transactionId, fakeHash1, fakeHash2 });
            var  merkleTreeRoot   = binaryMerkleTree.Root;
            var  merklePath       = binaryMerkleTree.GenerateMerklePath(0);
            Hash fakeTransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot");
            var  parentChainBlockData            = CreateParentChainBlockData(parentChainHeightOfCreation, parentChainId,
                                                                              fakeTransactionStatusMerkleRoot);

            long sideChainHeight = 1;

            parentChainBlockData.IndexedMerklePath.Add(sideChainHeight, merklePath);
            var crossChainBlockData = new CrossChainBlockData
            {
                ParentChainBlockData = { parentChainBlockData }
            };

            var indexingTx = await GenerateTransactionAsync(CrossChainContractAddress,
                                                            CrossChainConstants.CrossChainIndexingMethodName, null, crossChainBlockData);

            var block = await MineAsync(new List <Transaction> {
                indexingTx
            });

            var crossChainMerkleProofContext = CrossChainMerkleProofContext.Parser.ParseFrom(
                await CallContractMethodAsync(CrossChainContractAddress,
                                              nameof(CrossChainContractContainer.CrossChainContractStub
                                                     .GetBoundParentChainHeightAndMerklePathByHeight),
                                              new SInt64Value()
            {
                Value = sideChainHeight
            }));

            Assert.Equal(merklePath.ToByteString(),
                         crossChainMerkleProofContext.MerklePathForParentChainRoot.ToByteString());
            var calculatedRoot = crossChainMerkleProofContext.MerklePathForParentChainRoot
                                 .ComputeRootWithLeafNode(transactionId);

            Assert.Equal(merkleTreeRoot, calculatedRoot);
        }
Beispiel #28
0
        public void SingleNodeTest()
        {
            var tree = new BinaryMerkleTree();

            string hex = "5a7d71da020cae179a0dfe82bd3c967e1573377578f4cc87bc21f74f2556c0ef";

            tree.AddNode(CreateLeafFromHex(hex));

            //See if the hash of merkle tree is equal to the element’s hash.
            var root     = tree.ComputeRootHash();
            var expected = GetHashFromHexString(hex, hex);

            Assert.Equal(expected, root);
        }
Beispiel #29
0
        public static ByteString ExtractCrossChainExtraDataFromCrossChainBlockData(
            this IndexedSideChainBlockData indexedSideChainBlockData)
        {
            var txRootHashList = indexedSideChainBlockData.SideChainBlockDataList
                                 .Select(scb => scb.TransactionStatusMerkleTreeRoot).ToList();

            var calculatedSideChainTransactionsRoot = BinaryMerkleTree.FromLeafNodes(txRootHashList).Root;

            return(new CrossChainExtraData
            {
                TransactionStatusMerkleTreeRoot = calculatedSideChainTransactionsRoot
            }
                   .ToByteString());
        }
        public async Task CrossChain_MerklePath()
        {
            int  parentChainId = 123;
            long lockedToken   = 10;
            var  sideChainId   = await InitAndCreateSideChain(parentChainId, lockedToken);

            var txHash           = Hash.FromString("sideChainBlockHash");
            var binaryMerkleTree = new BinaryMerkleTree();
            var fakeHash1        = Hash.FromString("fake1");
            var fakeHash2        = Hash.FromString("fake2");

            binaryMerkleTree.AddNodes(new[] { txHash, fakeHash1, fakeHash2 });
            var  merkleTreeRoot = binaryMerkleTree.ComputeRootHash();
            var  merklePath     = binaryMerkleTree.GenerateMerklePath(0);
            Hash fakeTransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot");
            var  parentChainBlockData            = new ParentChainBlockData
            {
                Root = new ParentChainBlockRootInfo
                {
                    ParentChainHeight           = 1,
                    ParentChainId               = parentChainId,
                    TransactionStatusMerkleRoot = fakeTransactionStatusMerkleRoot
                }
            };
            long sideChainHeight = 1;

            parentChainBlockData.IndexedMerklePath.Add(sideChainHeight, merklePath);
            var crossChainBlockData = new CrossChainBlockData
            {
                ParentChainBlockData = { parentChainBlockData }
            };

            var indexingTx = await GenerateTransactionAsync(CrossChainContractAddress,
                                                            CrossChainConstants.CrossChainIndexingMethodName, null, crossChainBlockData);

            var block = await MineAsync(new List <Transaction> {
                indexingTx
            });

            var crossChainMerkleProofContext = CrossChainMerkleProofContext.Parser.ParseFrom(await CallContractMethodAsync(CrossChainContractAddress,
                                                                                                                           nameof(CrossChainContract.GetBoundParentChainHeightAndMerklePathByHeight),
                                                                                                                           new SInt64Value()
            {
                Value = sideChainHeight
            }));

            Assert.Equal(merklePath, crossChainMerkleProofContext.MerklePathForParentChainRoot);
            Assert.Equal(merkleTreeRoot, crossChainMerkleProofContext.MerklePathForParentChainRoot.ComputeRootWith(txHash));
        }