public async Task FillExtraData_Test() { var merkleTreeRoot = HashHelper.ComputeFrom("MerkleTreeRoot"); var expected = new CrossChainExtraData { TransactionStatusMerkleTreeRoot = merkleTreeRoot }; var header = new BlockHeader { PreviousBlockHash = HashHelper.ComputeFrom("PreviousHash"), Height = 2 }; _crossChainTestHelper.AddFakeExtraData(header.PreviousBlockHash, expected); var bytes = await _crossChainBlockExtraDataProvider.GetBlockHeaderExtraDataAsync(header); Assert.Equal(expected.ToByteString(), bytes); }
private async Task <bool> ValidateCrossChainBlockDataAsync(CrossChainBlockData crossChainBlockData, CrossChainExtraData extraData, IBlock block) { var txRootHashList = crossChainBlockData.SideChainBlockData.Select(scb => scb.TransactionMerkleTreeRoot).ToList(); var calculatedSideChainTransactionsRoot = new BinaryMerkleTree().AddNodes(txRootHashList).ComputeRootHash(); // first check identity with the root in header if (extraData != null && !calculatedSideChainTransactionsRoot.Equals(extraData.SideChainTransactionsRoot) || extraData == null && !calculatedSideChainTransactionsRoot.Equals(Hash.Empty)) { return(false); } // check cache identity var res = await _crossChainDataProvider.ValidateSideChainBlockDataAsync( crossChainBlockData.SideChainBlockData.ToList(), block.Header.PreviousBlockHash, block.Height - 1) && await _crossChainDataProvider.ValidateParentChainBlockDataAsync( crossChainBlockData.ParentChainBlockData.ToList(), block.Header.PreviousBlockHash, block.Height - 1); return(res); }
public async Task FIllExtraData_TransactionPackingDisabled() { var merkleTreeRoot = HashHelper.ComputeFrom("MerkleTreeRoot"); var expected = new CrossChainExtraData { TransactionStatusMerkleTreeRoot = merkleTreeRoot }; var header = new BlockHeader { PreviousBlockHash = HashHelper.ComputeFrom("PreviousHash"), Height = 2 }; _crossChainTestHelper.AddFakeExtraData(header.PreviousBlockHash, expected); await _transactionPackingOptionProvider.SetTransactionPackingOptionAsync(new BlockIndex { BlockHash = header.PreviousBlockHash, BlockHeight = header.Height - 1 }, false); var bytes = await _crossChainBlockExtraDataProvider.GetBlockHeaderExtraDataAsync(header); Assert.Empty(bytes); }
public override void ConfigureServices(ServiceConfigurationContext context) { base.ConfigureServices(context); var dictionary = new Dictionary <long, Hash> { { 1, Hash.FromString("1") }, { 2, Hash.FromString("2") }, { 3, Hash.FromString("3") } }; Configure <GrpcCrossChainConfigOption>(option => { option.ListeningPort = 5001; option.ParentChainServerIp = "127.0.0.1"; option.ParentChainServerPort = 5000; }); Configure <CrossChainConfigOptions>(option => { option.ParentChainId = ChainHelper.ConvertChainIdToBase58(ChainHelper.GetChainId(1)); }); context.Services.AddTransient(provider => { var kernelTestHelper = context.Services.GetRequiredServiceLazy <KernelTestHelper>(); var mockBlockChainService = new Mock <IBlockchainService>(); mockBlockChainService.Setup(m => m.GetChainAsync()).Returns(() => { var chain = new Chain { LastIrreversibleBlockHeight = 10 }; return(Task.FromResult(chain)); }); mockBlockChainService.Setup(m => m.GetBlockHashByHeightAsync(It.IsAny <Chain>(), It.IsAny <long>(), It.IsAny <Hash>())) .Returns <Chain, long, Hash>((chain, height, hash) => { if (height > 0 && height <= 3) { return(Task.FromResult(dictionary[height])); } return(Task.FromResult <Hash>(null)); }); mockBlockChainService.Setup(m => m.GetBlockByHashAsync(It.IsAny <Hash>())).Returns <Hash>(hash => { foreach (var kv in dictionary) { if (kv.Value.Equals(hash)) { var block = kernelTestHelper.Value.GenerateBlock(kv.Key - 1, dictionary[kv.Key - 1]); return(Task.FromResult(block)); } } return(Task.FromResult <Block>(null)); }); return(mockBlockChainService.Object); }); context.Services.AddTransient(provider => { var mockBlockExtraDataService = new Mock <IBlockExtraDataService>(); mockBlockExtraDataService .Setup(m => m.GetExtraDataFromBlockHeader(It.IsAny <string>(), It.IsAny <BlockHeader>())).Returns( () => { var crossExtraData = new CrossChainExtraData() { TransactionStatusMerkleTreeRoot = Hash.FromString("SideChainBlockHeadersRoot"), }; return(ByteString.CopyFrom(crossExtraData.ToByteArray())); }); return(mockBlockExtraDataService.Object); }); context.Services.AddTransient(provider => { var mockCrossChainIndexingDataService = new Mock <ICrossChainIndexingDataService>(); mockCrossChainIndexingDataService .Setup(m => m.GetIndexedCrossChainBlockDataAsync(It.IsAny <Hash>(), It.IsAny <long>())) .Returns(() => { var crossChainBlockData = new CrossChainBlockData { SideChainBlockDataList = { new SideChainBlockData { ChainId = 123, Height = 1, TransactionStatusMerkleTreeRoot = Hash.FromString("fakeTransactionMerkleTree") } } }; return(Task.FromResult(crossChainBlockData)); }); mockCrossChainIndexingDataService .Setup(m => m.GetIndexedSideChainBlockDataAsync(It.IsAny <Hash>(), It.IsAny <long>())).Returns( () => { var indexedSideChainBlockData = new IndexedSideChainBlockData { SideChainBlockDataList = { new SideChainBlockData { ChainId = 123, Height = 1, TransactionStatusMerkleTreeRoot = Hash.FromString("fakeTransactionMerkleTree") } } }; return(Task.FromResult(indexedSideChainBlockData)); }); return(mockCrossChainIndexingDataService.Object); }); context.Services.AddTransient(provider => { var mockCrossChainClientProvider = new Mock <ICrossChainClientProvider>(); mockCrossChainClientProvider.Setup(m => m.CreateCrossChainClient(It.IsAny <CrossChainClientDto>())) .Returns(() => { var mockCrossChainClient = new Mock <ICrossChainClient>(); mockCrossChainClient.Setup(m => m.RequestChainInitializationDataAsync(It.IsAny <int>())).Returns( () => { var chainInitialization = new ChainInitializationData { CreationHeightOnParentChain = 1 }; return(Task.FromResult(chainInitialization)); }); mockCrossChainClient.Setup(m => m.RequestCrossChainDataAsync(It.IsAny <long>(), It.IsAny <Func <IBlockCacheEntity, bool> >())) .Returns(() => { var chainInitialization = new ChainInitializationData { CreationHeightOnParentChain = 1 }; return(Task.FromResult(chainInitialization)); }); return(mockCrossChainClient.Object); }); return(mockCrossChainClientProvider.Object); }); context.Services.AddSingleton <CrossChainPlugin>(); context.Services.AddSingleton <IConsensusExtraDataNameProvider, MockConsensusExtraDataProvider>(); }
public async Task FillExtraData_Test() { var fakeMerkleTreeRoot1 = Hash.FromString("fakeMerkleTreeRoot1"); var fakeMerkleTreeRoot2 = Hash.FromString("fakeMerkleTreeRoot2"); var fakeMerkleTreeRoot3 = Hash.FromString("fakeMerkleTreeRoot3"); int chainId1 = ChainHelper.ConvertBase58ToChainId("2112"); int chainId2 = ChainHelper.ConvertBase58ToChainId("2113"); int chainId3 = ChainHelper.ConvertBase58ToChainId("2114"); var fakeSideChainBlockDataList = new List <SideChainBlockData> { new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot1, ChainId = chainId1 }, new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot2, ChainId = chainId2 }, new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot3, ChainId = chainId3 } }; var list1 = new List <SideChainBlockData>(); var list2 = new List <SideChainBlockData>(); var list3 = new List <SideChainBlockData>(); list1.Add(fakeSideChainBlockDataList[0]); list2.Add(fakeSideChainBlockDataList[1]); list3.Add(fakeSideChainBlockDataList[2]); for (int i = 2; i < CrossChainConstants.DefaultBlockCacheEntityCount + 2; i++) { list1.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot1, ChainId = chainId1 }); list2.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot2, ChainId = chainId2 }); list3.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot3, ChainId = chainId3 }); } _crossChainTestHelper.AddFakePendingCrossChainIndexingProposal( new GetPendingCrossChainIndexingProposalOutput { Proposer = SampleAddress.AddressList[0], ProposalId = Hash.FromString("ProposalId"), ProposedCrossChainBlockData = new CrossChainBlockData { SideChainBlockDataList = { list1, list2, list3 } }, ToBeReleased = true, ExpiredTime = TimestampHelper.GetUtcNow().AddSeconds(10) }); _crossChainTestHelper.SetFakeLibHeight(1); var header = new BlockHeader { PreviousBlockHash = Hash.FromString("PreviousHash"), Height = 2 }; var sideChainTxMerkleTreeRoot = await _crossChainBlockExtraDataProvider.GetExtraDataForFillingBlockHeaderAsync(header); var merkleTreeRoot = BinaryMerkleTree .FromLeafNodes(list1.Concat(list2).Concat(list3).Select(sideChainBlockData => sideChainBlockData.TransactionStatusMerkleTreeRoot)).Root; var expected = new CrossChainExtraData { TransactionStatusMerkleTreeRoot = merkleTreeRoot }.ToByteString(); Assert.Equal(expected, sideChainTxMerkleTreeRoot); }
public void AddFakeExtraData(Hash previousHash, CrossChainExtraData crossChainExtraData) { _fakeCrossChainExtraData.Add(previousHash, crossChainExtraData); }
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 async Task FillExtraData_Test() { var fakeMerkleTreeRoot1 = Hash.FromString("fakeMerkleTreeRoot1"); var fakeMerkleTreeRoot2 = Hash.FromString("fakeMerkleTreeRoot2"); var fakeMerkleTreeRoot3 = Hash.FromString("fakeMerkleTreeRoot3"); int chainId1 = ChainHelper.ConvertBase58ToChainId("2112"); int chainId2 = ChainHelper.ConvertBase58ToChainId("2113"); int chainId3 = ChainHelper.ConvertBase58ToChainId("2114"); var fakeSideChainBlockDataList = new List <SideChainBlockData> { new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot1, ChainId = chainId1 }, new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot2, ChainId = chainId2 }, new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot3, ChainId = chainId3 } }; var list1 = new List <IBlockCacheEntity>(); var list2 = new List <IBlockCacheEntity>(); var list3 = new List <IBlockCacheEntity>(); list1.Add(fakeSideChainBlockDataList[0]); list2.Add(fakeSideChainBlockDataList[1]); list3.Add(fakeSideChainBlockDataList[2]); for (int i = 2; i < CrossChainConstants.MinimalBlockCacheEntityCount + 2; i++) { list1.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot1, ChainId = chainId1 }); list2.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot2, ChainId = chainId2 }); list3.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot3, ChainId = chainId3 }); } AddFakeCacheData(new Dictionary <int, List <IBlockCacheEntity> > { { chainId1, list1 }, { chainId2, list2 }, { chainId3, list3 } }); _crossChainTestHelper.AddFakeSideChainIdHeight(chainId1, 0); _crossChainTestHelper.AddFakeSideChainIdHeight(chainId2, 0); _crossChainTestHelper.AddFakeSideChainIdHeight(chainId3, 0); _crossChainTestHelper.SetFakeLibHeight(1); var header = new BlockHeader { PreviousBlockHash = Hash.FromString("PreviousHash"), Height = 2 }; var sideChainTxMerkleTreeRoot = await _crossChainBlockExtraDataProvider.GetExtraDataForFillingBlockHeaderAsync(header); var merkleTreeRoot = BinaryMerkleTree .FromLeafNodes(fakeSideChainBlockDataList.Select(sideChainBlockData => sideChainBlockData.TransactionStatusMerkleTreeRoot)).Root; var expected = new CrossChainExtraData { TransactionStatusMerkleTreeRoot = merkleTreeRoot }.ToByteString(); Assert.Equal(expected, sideChainTxMerkleTreeRoot); }
public async Task FillExtraData_Test() { var fakeMerkleTreeRoot1 = HashHelper.ComputeFrom("fakeMerkleTreeRoot1"); var fakeMerkleTreeRoot2 = HashHelper.ComputeFrom("fakeMerkleTreeRoot2"); var fakeMerkleTreeRoot3 = HashHelper.ComputeFrom("fakeMerkleTreeRoot3"); int chainId1 = ChainHelper.ConvertBase58ToChainId("2112"); int chainId2 = ChainHelper.ConvertBase58ToChainId("2113"); int chainId3 = ChainHelper.ConvertBase58ToChainId("2114"); var fakeSideChainBlockDataList = new List <SideChainBlockData> { new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot1, ChainId = chainId1 }, new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot2, ChainId = chainId2 }, new SideChainBlockData { Height = 1, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot3, ChainId = chainId3 } }; var list1 = new List <SideChainBlockData>(); var list2 = new List <SideChainBlockData>(); var list3 = new List <SideChainBlockData>(); list1.Add(fakeSideChainBlockDataList[0]); list2.Add(fakeSideChainBlockDataList[1]); list3.Add(fakeSideChainBlockDataList[2]); for (int i = 2; i < CrossChainConstants.DefaultBlockCacheEntityCount + 2; i++) { list1.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot1, ChainId = chainId1 }); list2.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot2, ChainId = chainId2 }); list3.Add(new SideChainBlockData { Height = i, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot3, ChainId = chainId3 }); } _crossChainTestHelper.AddFakePendingCrossChainIndexingProposal(chainId1, CreatePendingChainIndexingProposalStatus(SampleAddress.AddressList[0], HashHelper.ComputeFrom("ProposalId"), new CrossChainBlockData { SideChainBlockDataList = { list1 } })); _crossChainTestHelper.AddFakePendingCrossChainIndexingProposal(chainId2, CreatePendingChainIndexingProposalStatus(SampleAddress.AddressList[0], HashHelper.ComputeFrom("ProposalId"), new CrossChainBlockData { SideChainBlockDataList = { list2 } })); _crossChainTestHelper.AddFakePendingCrossChainIndexingProposal(chainId3, CreatePendingChainIndexingProposalStatus(SampleAddress.AddressList[0], HashHelper.ComputeFrom("ProposalId"), new CrossChainBlockData { SideChainBlockDataList = { list3 } }) ); _crossChainTestHelper.SetFakeLibHeight(1); var header = new BlockHeader { PreviousBlockHash = HashHelper.ComputeFrom("PreviousHash"), Height = 2 }; var sideChainTxMerkleTreeRoot = await _crossChainIndexingDataService.PrepareExtraDataForNextMiningAsync(header.PreviousBlockHash, header.Height - 1); var merkleTreeRoot = BinaryMerkleTree .FromLeafNodes(list1.Concat(list2).Concat(list3).Select(sideChainBlockData => sideChainBlockData.TransactionStatusMerkleTreeRoot)).Root; var expected = new CrossChainExtraData { TransactionStatusMerkleTreeRoot = merkleTreeRoot }.ToByteString(); Assert.Equal(expected, sideChainTxMerkleTreeRoot); }
public override void ConfigureServices(ServiceConfigurationContext context) { base.ConfigureServices(context); context.Services.AddSingleton <CrossChainCommunicationTestHelper>(); Configure <CrossChainConfigOptions>(option => { option.ParentChainId = ChainHelper.ConvertChainIdToBase58(ChainHelper.GetChainId(1)); }); context.Services.AddTransient(provider => { var kernelTestHelper = context.Services.GetRequiredServiceLazy <KernelTestHelper>(); var crossChainCommunicationTestHelper = context.Services.GetRequiredServiceLazy <CrossChainCommunicationTestHelper>().Value; var mockBlockChainService = new Mock <IBlockchainService>(); mockBlockChainService.Setup(m => m.GetChainAsync()).Returns(() => { var chain = new Chain { LastIrreversibleBlockHeight = 10 }; return(Task.FromResult(chain)); }); mockBlockChainService.Setup(m => m.GetBlockHashByHeightAsync(It.IsAny <Chain>(), It.IsAny <long>(), It.IsAny <Hash>())) .Returns <Chain, long, Hash>((chain, height, hash) => Task.FromResult(crossChainCommunicationTestHelper.GetBlockHashByHeight(height))); mockBlockChainService.Setup(m => m.GetBlockByHashAsync(It.IsAny <Hash>())).Returns <Hash>(hash => { if (!crossChainCommunicationTestHelper.TryGetHeightByHash(hash, out var height)) { return(Task.FromResult <Block>(null)); } var block = kernelTestHelper.Value.GenerateBlock(height - 1, crossChainCommunicationTestHelper.GetBlockHashByHeight(height - 1)); return(Task.FromResult(block)); }); return(mockBlockChainService.Object); }); context.Services.AddTransient(provider => { var crossChainCommunicationTestHelper = context.Services.GetRequiredServiceLazy <CrossChainCommunicationTestHelper>().Value; var mockBlockExtraDataService = new Mock <IBlockExtraDataService>(); mockBlockExtraDataService .Setup(m => m.GetExtraDataFromBlockHeader(It.IsAny <string>(), It.IsAny <BlockHeader>())).Returns( () => { var crossExtraData = new CrossChainExtraData { TransactionStatusMerkleTreeRoot = BinaryMerkleTree .FromLeafNodes( crossChainCommunicationTestHelper.IndexedSideChainBlockData .SideChainBlockDataList.Select(scb => scb.TransactionStatusMerkleTreeRoot)) .Root, }; return(ByteString.CopyFrom(crossExtraData.ToByteArray())); }); return(mockBlockExtraDataService.Object); }); context.Services.AddTransient(provider => { var crossChainCommunicationTestHelper = context.Services.GetRequiredServiceLazy <CrossChainCommunicationTestHelper>().Value; var mockCrossChainIndexingDataService = new Mock <ICrossChainIndexingDataService>(); var irreversibleBlockStateProvider = context.Services.GetRequiredServiceLazy <IIrreversibleBlockStateProvider>(); mockCrossChainIndexingDataService.Setup(service => service.GetNonIndexedBlockAsync(It.IsAny <long>())) .Returns <long>(async height => await irreversibleBlockStateProvider.Value .GetNotIndexedIrreversibleBlockByHeightAsync(height)); mockCrossChainIndexingDataService .Setup(m => m.GetIndexedSideChainBlockDataAsync(It.IsAny <Hash>(), It.IsAny <long>())).Returns( () => { var indexedSideChainBlockData = crossChainCommunicationTestHelper.IndexedSideChainBlockData; return(Task.FromResult(indexedSideChainBlockData)); }); return(mockCrossChainIndexingDataService.Object); }); context.Services.AddTransient(provider => { var crossChainCommunicationTestHelper = context.Services.GetRequiredServiceLazy <CrossChainCommunicationTestHelper>().Value; var mockCrossChainClientProvider = new Mock <ICrossChainClientProvider>(); ICrossChainClient client; mockCrossChainClientProvider .Setup(m => m.TryGetClient(It.IsAny <int>(), out client)) .Callback(new TryGetClientCallback((int chainId, out ICrossChainClient crossChainClient) => { if (!crossChainCommunicationTestHelper.TryGetCrossChainClientCreationContext(chainId, out _)) { crossChainClient = null; return; } bool isConnected = crossChainCommunicationTestHelper.CheckClientConnected(chainId); crossChainClient = MockCrossChainClient(chainId, isConnected, entity => { crossChainCommunicationTestHelper.SetClientConnected(-1, true); return(true); }); })) .Returns <int, ICrossChainClient>((chainId, client) => crossChainCommunicationTestHelper.TryGetCrossChainClientCreationContext(chainId, out _)); mockCrossChainClientProvider .Setup(c => c.AddOrUpdateClient(It.IsAny <CrossChainClientCreationContext>())) .Returns <CrossChainClientCreationContext>( crossChainClientCreationContext => CreateAndAddClient(crossChainCommunicationTestHelper, crossChainClientCreationContext)); mockCrossChainClientProvider.Setup(c => c.CreateChainInitializationDataClient(It.IsAny <CrossChainClientCreationContext>())).Returns <CrossChainClientCreationContext>( crossChainClientCreationContext => CreateAndAddClient(crossChainCommunicationTestHelper, crossChainClientCreationContext)); return(mockCrossChainClientProvider.Object); }); context.Services.AddSingleton <IConsensusExtraDataKeyProvider, MockConsensusExtraDataProvider>(); }