public async Task RecordParentChainData_Twice()
        {
            int parentChainId = 123;

            await InitAndCreateSideChain(parentChainId);

            Hash fakeTransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot");
            var  parentChainBlockData            = new ParentChainBlockData
            {
                Root = new ParentChainBlockRootInfo
                {
                    ParentChainId               = parentChainId,
                    ParentChainHeight           = 1,
                    TransactionStatusMerkleRoot = fakeTransactionStatusMerkleRoot
                }
            };
            var crossChainBlockData = new CrossChainBlockData
            {
                ParentChainBlockData = { parentChainBlockData }
            };

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

            await MineAsync(new List <Transaction> {
                tx
            });

            (await GetTransactionResult(tx.GetHash())).Status.ShouldBe(TransactionResultStatus.Mined);
            var txRes = await ExecuteContractWithMiningAsync(CrossChainContractAddress,
                                                             CrossChainConstants.CrossChainIndexingMethodName, crossChainBlockData);

            Assert.True(txRes.Status == TransactionResultStatus.Failed);
        }
        public async Task <ParentChainBlockData> ResponseParentChainBlockDataAsync(long requestHeight, int remoteSideChainId)
        {
            var block = await _crossChainService.GetNonIndexedBlockAsync(requestHeight);

            if (block == null)
            {
                return(null);
            }
            var parentChainBlockData = new ParentChainBlockData
            {
                Height = block.Height, ChainId = block.Header.ChainId
            };

            parentChainBlockData = FillExtraDataInResponse(parentChainBlockData, block.Header);

            if (parentChainBlockData.CrossChainExtraData == null)
            {
                return(parentChainBlockData);
            }

            var indexedSideChainBlockDataResult = await GetIndexedSideChainBlockDataResultAsync(block);

            var enumerableMerklePath = GetEnumerableMerklePath(indexedSideChainBlockDataResult, remoteSideChainId);

            foreach (var kv in enumerableMerklePath)
            {
                parentChainBlockData.IndexedMerklePath.Add(kv.Key, kv.Value);
            }

            return(parentChainBlockData);
        }
        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);
        }
        public async Task RecordParentChainData()
        {
            int parentChainId = 123;

            await InitAndCreateSideChain(parentChainId);

            Hash fakeTransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot");
            var  parentChainBlockData            = new ParentChainBlockData
            {
                Root = new ParentChainBlockRootInfo
                {
                    ParentChainId               = parentChainId,
                    ParentChainHeight           = 1,
                    TransactionStatusMerkleRoot = fakeTransactionStatusMerkleRoot
                }
            };
            var crossChainBlockData = new CrossChainBlockData
            {
                ParentChainBlockData = { parentChainBlockData }
            };

            var txRes = await ExecuteContractWithMiningAsync(CrossChainContractAddress,
                                                             CrossChainConstants.CrossChainIndexingMethodName, crossChainBlockData);

            Assert.True(txRes.Status == TransactionResultStatus.Mined);
        }
        public async Task RecordParentChainData_DiscontinuousData()
        {
            int parentChainId = 123;

            await InitAndCreateSideChain(parentChainId);

            var parentChainBlockData1 = new ParentChainBlockData
            {
                Root = new ParentChainBlockRootInfo
                {
                    ParentChainId     = parentChainId,
                    ParentChainHeight = 1
                }
            };

            var parentChainBlockData2 = new ParentChainBlockData
            {
                Root = new ParentChainBlockRootInfo
                {
                    ParentChainId     = parentChainId,
                    ParentChainHeight = 3
                }
            };
            var crossChainBlockData = new CrossChainBlockData
            {
                ParentChainBlockData = { parentChainBlockData1, parentChainBlockData2 }
            };

            var txRes = await ExecuteContractWithMiningAsync(CrossChainContractAddress,
                                                             CrossChainConstants.CrossChainIndexingMethodName, crossChainBlockData);

            Assert.True(txRes.Status == TransactionResultStatus.Failed);
        }
Esempio n. 6
0
 private void AssertParentChainBlock(int parentChainId, long currentRecordedHeight,
                                     ParentChainBlockData parentChainBlockData)
 {
     Assert(parentChainId == parentChainBlockData.ChainId, "Wrong parent chain id.");
     Assert(currentRecordedHeight + 1 == parentChainBlockData.Height,
            $"Parent chain block info at height {currentRecordedHeight + 1} is needed, not {parentChainBlockData.Height}");
     Assert(parentChainBlockData.TransactionStatusMerkleTreeRoot != null,
            "Parent chain transaction status merkle tree root needed.");
 }
        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));
        }
Esempio n. 8
0
        private ParentChainBlockData FillExtraDataInResponse(ParentChainBlockData parentChainBlockData, BlockHeader blockHeader)
        {
            parentChainBlockData.TransactionStatusMerkleTreeRoot = blockHeader.MerkleTreeRootOfTransactionStatus;

            var crossChainExtraByteString = GetExtraDataFromHeader(blockHeader, "CrossChain");
            var crossChainExtra           = crossChainExtraByteString == ByteString.Empty || crossChainExtraByteString == null
                ? null
                : CrossChainExtraData.Parser.ParseFrom(crossChainExtraByteString);

            parentChainBlockData.CrossChainExtraData = crossChainExtra;

            parentChainBlockData.ExtraData.Add(GetExtraDataForExchange(blockHeader,
                                                                       new[] { "Consensus" }));
            return(parentChainBlockData);
        }
Esempio n. 9
0
        private ParentChainBlockData FillExtraDataInResponse(ParentChainBlockData parentChainBlockData,
                                                             BlockHeader blockHeader)
        {
            parentChainBlockData.TransactionStatusMerkleTreeRoot = blockHeader.MerkleTreeRootOfTransactionStatus;

            var crossChainExtraByteString =
                GetExtraDataFromHeader(blockHeader, CrossChainConstants.CrossChainExtraDataNamePrefix);

            var crossChainExtra = crossChainExtraByteString.IsNullOrEmpty()
                ? null
                : CrossChainExtraData.Parser.ParseFrom(crossChainExtraByteString);

            parentChainBlockData.CrossChainExtraData = crossChainExtra;

            parentChainBlockData.ExtraData.Add(GetExtraDataForExchange(blockHeader,
                                                                       new[] { _consensusExtraDataNameProvider.ExtraDataName }));
            return(parentChainBlockData);
        }
        public async Task GetParentChainHeight()
        {
            int  parentChainId     = 123;
            long parentChainHeight = 1;

            await InitAndCreateSideChain(parentChainId);

            Hash fakeTransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot");
            var  parentChainBlockData            = new ParentChainBlockData
            {
                Root = new ParentChainBlockRootInfo
                {
                    ParentChainId               = parentChainId,
                    ParentChainHeight           = parentChainHeight,
                    TransactionStatusMerkleRoot = fakeTransactionStatusMerkleRoot
                }
            };
            var crossChainBlockData = new CrossChainBlockData
            {
                ParentChainBlockData = { parentChainBlockData }
            };

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

            await MineAsync(new List <Transaction> {
                tx
            });

            (await GetTransactionResult(tx.GetHash())).Status.ShouldBe(TransactionResultStatus.Mined);

            var height = SInt64Value.Parser.ParseFrom(await CallContractMethodAsync(
                                                          CrossChainContractAddress,
                                                          nameof(CrossChainContract.GetParentChainHeight),
                                                          new Empty())).Value;

            Assert.True(parentChainHeight == height);
        }
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            base.ConfigureServices(context);

            var services = context.Services;

            services.AddTransient(o =>
            {
                var kernelTestHelper = context.Services.GetRequiredServiceLazy <KernelTestHelper>();
                var mockService      = new Mock <IBlockchainService>();
                mockService.Setup(m => m.GetChainAsync())
                .Returns(Task.FromResult(new Chain
                {
                    LastIrreversibleBlockHeight = 10
                }));
                mockService.Setup(m =>
                                  m.GetBlockHashByHeightAsync(It.IsAny <Chain>(), It.IsAny <long>(), It.IsAny <Hash>()))
                .Returns(Task.FromResult(Hash.FromString("hash")));
                mockService.Setup(m => m.GetBlockByHashAsync(It.IsAny <Hash>()))
                .Returns(() =>
                {
                    var previousBlockHash = Hash.FromString("previousBlockHash");
                    return(Task.FromResult(kernelTestHelper.Value.GenerateBlock(9, previousBlockHash)));
                });
                return(mockService.Object);
            });

            services.AddTransient(o =>
            {
                var mockCrossChainDataProvider = new Mock <ICrossChainService>();
                mockCrossChainDataProvider
                .Setup(c => c.GetChainInitializationDataAsync(It.IsAny <int>())).Returns(async() =>
                                                                                         await Task.FromResult(new ChainInitializationData
                {
                    CreationHeightOnParentChain = 1,
                }));
                return(mockCrossChainDataProvider.Object);
            });

            services.AddTransient(o =>
            {
                var mockCrossChainResponseService = new Mock <ICrossChainResponseService>();
                mockCrossChainResponseService
                .Setup(c => c.ResponseParentChainBlockDataAsync(It.IsAny <long>(), It.IsAny <int>())).Returns <long, int>(
                    (height, chainId) =>
                {
                    if (height > 100)
                    {
                        return(Task.FromResult <ParentChainBlockData>(null));
                    }

                    var parentChanBlockData = new ParentChainBlockData
                    {
                        ChainId = chainId,
                        Height  = height,
                        TransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot")
                    };
                    return(Task.FromResult(parentChanBlockData));
                });
                mockCrossChainResponseService
                .Setup(c => c.ResponseSideChainBlockDataAsync(It.IsAny <long>())).Returns(
                    () =>
                {
                    var sideChanBlockData = new SideChainBlockData()
                    {
                        ChainId = ChainHelper.GetChainId(1),
                        Height  = 10,
                    };
                    return(Task.FromResult(sideChanBlockData));
                });
                mockCrossChainResponseService
                .Setup(c => c.ResponseChainInitializationDataFromParentChainAsync(It.IsAny <int>())).Returns(
                    () =>
                {
                    var chainInitializationData = new ChainInitializationData()
                    {
                        CreationHeightOnParentChain = 1
                    };
                    return(Task.FromResult(chainInitializationData));
                });
                return(mockCrossChainResponseService.Object);
            });

            services.AddTransient(o =>
            {
                var mockService = new Mock <ICrossChainCacheEntityService>();
                return(mockService.Object);
            });
        }