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); }
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)); }
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); }
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); }); }