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); }
public override Empty RecordCrossChainData(CrossChainBlockData crossChainBlockData) { //Assert(IsMiner(), "Not authorized to do this."); var indexedCrossChainData = State.IndexedSideChainBlockData[Context.CurrentHeight]; Assert(indexedCrossChainData == null); // This should not fail. var indexedParentChainBlockData = IndexParentChainBlockData(crossChainBlockData.ParentChainBlockData); if (indexedParentChainBlockData.ParentChainBlockData.Count > 0) { State.LastIndexedParentChainBlockData.Value = indexedParentChainBlockData; Context.Fire(new ParentChainBlockDataIndexed()); } var indexedSideChainBlockData = IndexSideChainBlockData(crossChainBlockData.SideChainBlockData); State.IndexedSideChainBlockData[Context.CurrentHeight] = indexedSideChainBlockData; if (indexedSideChainBlockData.SideChainBlockData.Count > 0) { Context.Fire(new SideChainBlockDataIndexed()); } return(new Empty()); }
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); }
private async Task <bool> ValidateCrossChainBlockDataAsync(CrossChainBlockData crossChainBlockData, Hash blockHash, long blockHeight) { if (CrossChainConfigOptions.CurrentValue.CrossChainDataValidationIgnored) { return(true); } var sideChainBlockDataValidationResult = await _crossChainIndexingDataService.ValidateSideChainBlockDataAsync( crossChainBlockData.SideChainBlockData.ToList(), blockHash, blockHeight); if (!sideChainBlockDataValidationResult) { return(false); } var parentChainBlockDataValidationResult = await _crossChainIndexingDataService.ValidateParentChainBlockDataAsync( crossChainBlockData.ParentChainBlockData.ToList(), blockHash, blockHeight); if (!parentChainBlockDataValidationResult) { return(false); } return(true); }
public async Task GetChainInitializationContext_Success() { var parentChainId = 123; var lockedToken = 10L; long parentChainHeightOfCreation = 10; var sideChainId = await InitAndCreateSideChainAsync(parentChainHeightOfCreation, parentChainId, lockedToken); var fakeSideChainBlockHash = Hash.FromString("sideChainBlockHash"); var fakeTxMerkleTreeRoot = Hash.FromString("txMerkleTreeRoot"); var sideChainBlockData = CreateSideChainBlockData(fakeSideChainBlockHash, 1, sideChainId, fakeTxMerkleTreeRoot); var crossChainBlockData = new CrossChainBlockData { SideChainBlockData = {sideChainBlockData} }; var indexingRes = await CrossChainContractStub.RecordCrossChainData.SendAsync(crossChainBlockData); Assert.True(indexingRes.TransactionResult.Status == TransactionResultStatus.Mined); //not exsit chain id var error = await CrossChainContractStub.GetChainInitializationData.CallWithExceptionAsync(new SInt32Value {Value = parentChainId}); error.Value.ShouldContain("Side chain not found."); //valid chain id var chainInitializationContext = await CrossChainContractStub.GetChainInitializationData.CallAsync(new SInt32Value {Value = sideChainId}); chainInitializationContext.ChainId.ShouldBe(sideChainId); chainInitializationContext.Creator.ShouldBe(Address.FromPublicKey(DefaultKeyPair.PublicKey)); }
public async Task Validate_WithoutEmptyInput_Test() { int chainId = _chainOptions.ChainId; var blockInfoCache = new List <IBlockCacheEntity>(); for (int i = 0; i <= CrossChainConstants.DefaultBlockCacheEntityCount; i++) { blockInfoCache.Add(new SideChainBlockData { Height = 1 + i, ChainId = chainId }); } _crossChainTestHelper.AddFakeSideChainIdHeight(chainId, 0); var fakeCache = new Dictionary <int, List <IBlockCacheEntity> > { { chainId, blockInfoCache } }; AddFakeCacheData(fakeCache); var crossChainBlockData = new CrossChainBlockData(); var res = await _crossChainIndexingDataValidationService.ValidateCrossChainIndexingDataAsync(crossChainBlockData, Hash.Empty, 1); Assert.True(res); }
/// <summary> /// This method returns cross chain data. /// </summary> /// <param name="blockHash"></param> /// <param name="blockHeight"></param> /// <returns></returns> public async Task <CrossChainBlockData> GetCrossChainBlockDataForNextMiningAsync(Hash blockHash, long blockHeight) { if (!_transactionInclusivenessProvider.IsTransactionPackable) { return(null); } Logger.LogTrace("Try get cross chain data for mining."); var sideChainBlockData = await GetNonIndexedSideChainBlockDataAsync(blockHash, blockHeight); var parentChainBlockData = await GetNonIndexedParentChainBlockDataAsync(blockHash, blockHeight); if (sideChainBlockData.Count == 0 && parentChainBlockData.Count == 0) { return(null); } var crossChainBlockData = new CrossChainBlockData(); crossChainBlockData.ParentChainBlockData.AddRange(parentChainBlockData); crossChainBlockData.SideChainBlockData.AddRange(sideChainBlockData); crossChainBlockData.PreviousBlockHeight = blockHeight; _indexedCrossChainBlockDataProvider.SetIndexedBlockData(blockHash, crossChainBlockData); return(crossChainBlockData); }
public async Task RecordSideChainData() { var parentChainId = 123; var lockedToken = 10L; long parentChainHeightOfCreation = 10; var sideChainId = await InitAndCreateSideChainAsync(parentChainHeightOfCreation, parentChainId, lockedToken); var fakeSideChainBlockHash = Hash.FromString("sideChainBlockHash"); var fakeTxMerkleTreeRoot = Hash.FromString("txMerkleTreeRoot"); var sideChainBlockData = CreateSideChainBlockData(fakeSideChainBlockHash, 1, sideChainId, fakeTxMerkleTreeRoot); var crossChainBlockData = new CrossChainBlockData { SideChainBlockData = {sideChainBlockData} }; var indexingTx = await CrossChainContractStub.RecordCrossChainData.SendAsync(crossChainBlockData); Assert.True(indexingTx.TransactionResult.Status == TransactionResultStatus.Mined); var balance = await CrossChainContractStub.GetSideChainBalance.CallAsync(new SInt32Value {Value = sideChainId}); Assert.Equal(lockedToken - 1, balance.Value); var blockHeader = await BlockchainService.GetBestChainLastBlockHeaderAsync(); var indexedCrossChainBlockData = await CrossChainContractStub.GetIndexedCrossChainBlockDataByHeight.CallAsync(new SInt64Value {Value = blockHeader.Height}); Assert.Equal(crossChainBlockData, indexedCrossChainBlockData); }
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 GetParentChainHeight() { int parentChainId = 123; long parentChainHeightOfCreation = 10; await InitAndCreateSideChainAsync(parentChainHeightOfCreation, parentChainId); Hash fakeTransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot"); var parentChainBlockData = CreateParentChainBlockData(parentChainHeightOfCreation, parentChainId, fakeTransactionStatusMerkleRoot); var crossChainBlockData = new CrossChainBlockData { ParentChainBlockData = { parentChainBlockData } }; var tx = await GenerateTransactionAsync(CrossChainContractAddress, CrossChainConstants.CrossChainIndexingMethodName, null, crossChainBlockData); await MineAsync(new List <Transaction> { tx }); (await GetTransactionResultAsync(tx.GetHash())).Status.ShouldBe(TransactionResultStatus.Mined); var height = SInt64Value.Parser.ParseFrom(await CallContractMethodAsync( CrossChainContractAddress, nameof(CrossChainContractContainer.CrossChainContractStub.GetParentChainHeight), new Empty())).Value; Assert.True(parentChainHeightOfCreation == height); }
public async Task RecordParentChainData_Twice() { int parentChainId = 123; long parentChainHeightOfCreation = 10; await InitAndCreateSideChainAsync(parentChainHeightOfCreation, parentChainId); Hash fakeTransactionStatusMerkleRoot = Hash.FromString("TransactionStatusMerkleRoot"); var parentChainBlockData = CreateParentChainBlockData(parentChainHeightOfCreation, parentChainId, fakeTransactionStatusMerkleRoot); var crossChainBlockData = new CrossChainBlockData { ParentChainBlockData = { parentChainBlockData } }; var tx = await GenerateTransactionAsync(CrossChainContractAddress, CrossChainConstants.CrossChainIndexingMethodName, null, crossChainBlockData); await MineAsync(new List <Transaction> { tx }); (await GetTransactionResultAsync(tx.GetHash())).Status.ShouldBe(TransactionResultStatus.Mined); var txRes = await ExecuteContractWithMiningAsync(CrossChainContractAddress, CrossChainConstants.CrossChainIndexingMethodName, crossChainBlockData); Assert.True(txRes.Status == TransactionResultStatus.Failed); }
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()); }
private bool ValidateBlockExtraDataAsync(CrossChainBlockData crossChainBlockData, ByteString extraData) { var expected = _crossChainIndexingDataService.ExtractCrossChainExtraDataFromCrossChainBlockData(crossChainBlockData); return(expected.Equals(extraData)); }
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 override Empty RecordCrossChainData(CrossChainBlockData input) { var crossChainBlockData = input; //Assert(IsMiner(), "Not authorized to do this."); var indexedCrossChainData = State.IndexedCrossChainBlockData[Context.CurrentHeight]; Assert(indexedCrossChainData == null); // This should not fail. var sideChainBlockData = crossChainBlockData.SideChainBlockData; IndexParentChainBlockInfo(crossChainBlockData.ParentChainBlockData.ToArray()); var indexedSideChainBlockData = IndexSideChainBlockInfo(sideChainBlockData.ToArray()); var actualCrossChainData = new CrossChainBlockData(); actualCrossChainData.ParentChainBlockData.AddRange(crossChainBlockData.ParentChainBlockData); actualCrossChainData.SideChainBlockData.AddRange(indexedSideChainBlockData); State.IndexedCrossChainBlockData[Context.CurrentHeight] = actualCrossChainData; // Context.FireEvent(new CrossChainIndexingEvent // { // SideChainTransactionsMerkleTreeRoot = calculatedRoot, // CrossChainBlockData = crossChainBlockData, // Sender = Context.Sender // for validation // }); return(new Empty()); }
public async Task GetIndexedCrossChainBlockData_WithIndex_Test() { var chainId = _chainOptions.ChainId; var fakeMerkleTreeRoot1 = Hash.FromString("fakeMerkleTreeRoot1"); var fakeSideChainBlockData = new SideChainBlockData { Height = 1, ChainId = chainId, TransactionStatusMerkleTreeRoot = fakeMerkleTreeRoot1 }; var fakeIndexedCrossChainBlockData = new CrossChainBlockData(); fakeIndexedCrossChainBlockData.SideChainBlockData.AddRange(new [] { fakeSideChainBlockData }); _crossChainTestHelper.AddFakeIndexedCrossChainBlockData(fakeSideChainBlockData.Height, fakeIndexedCrossChainBlockData); _crossChainTestHelper.AddFakeSideChainIdHeight(chainId, 0); AddFakeCacheData(new Dictionary <int, List <IBlockCacheEntity> > { { chainId, new List <IBlockCacheEntity> { fakeSideChainBlockData } } }); var res = await _crossChainIndexingDataService.GetIndexedCrossChainBlockDataAsync( fakeSideChainBlockData.BlockHeaderHash, 1); Assert.True(res.SideChainBlockData[0].Height == fakeSideChainBlockData.Height); Assert.True(res.SideChainBlockData[0].ChainId == chainId); }
public override Empty RecordCrossChainData(CrossChainBlockData crossChainBlockData) { Context.LogDebug(() => "Start RecordCrossChainData."); AssertCurrentMiner(); var indexedCrossChainData = State.IndexedSideChainBlockData[Context.CurrentHeight]; Assert(indexedCrossChainData == null); // This should not fail without evil miners. var indexedParentChainBlockData = IndexParentChainBlockData(crossChainBlockData.ParentChainBlockData); if (indexedParentChainBlockData.ParentChainBlockData.Count > 0) { State.LastIndexedParentChainBlockData.Value = indexedParentChainBlockData; Context.Fire(new ParentChainBlockDataIndexed()); } var indexedSideChainBlockData = IndexSideChainBlockData(crossChainBlockData.SideChainBlockData); State.IndexedSideChainBlockData.Set(Context.CurrentHeight, indexedSideChainBlockData); if (indexedSideChainBlockData.SideChainBlockData.Count > 0) { Context.Fire(new SideChainBlockDataIndexed()); } Context.LogDebug(() => "Finished RecordCrossChainData."); return(new Empty()); }
public async Task GenerateTransactions_Test() { var sideChainId = 123; var sideChainBlockInfoCache = new List <IBlockCacheEntity>(); var previousBlockHash = Hash.FromString("PreviousBlockHash"); var previousBlockHeight = 1; var crossChainBlockData = new CrossChainBlockData { PreviousBlockHeight = previousBlockHeight }; var cachingCount = 5; for (int i = 1; i < cachingCount + CrossChainConstants.DefaultBlockCacheEntityCount; i++) { var sideChainBlockData = new SideChainBlockData() { ChainId = sideChainId, Height = (i + 1), TransactionStatusMerkleTreeRoot = Hash.FromString((sideChainId + 1).ToString()) }; sideChainBlockInfoCache.Add(sideChainBlockData); if (i <= CrossChainConstants.DefaultBlockCacheEntityCount) { crossChainBlockData.SideChainBlockDataList.Add(sideChainBlockData); } } _crossChainTestHelper.AddFakeSideChainIdHeight(sideChainId, 1); AddFakeCacheData(new Dictionary <int, List <IBlockCacheEntity> > { { sideChainId, sideChainBlockInfoCache } }); var res = await _crossChainIndexingDataService.PrepareExtraDataForNextMiningAsync(previousBlockHash, previousBlockHeight); Assert.Empty(res); var smartContractAddress = SampleAddress.AddressList[0]; _smartContractAddressService.SetAddress(CrossChainSmartContractAddressNameProvider.Name, smartContractAddress); var transactions = await _crossChainIndexingTransactionGenerator.GenerateTransactionsAsync(SampleAddress.AddressList[0], previousBlockHeight, previousBlockHash); transactions.Count.ShouldBe(1); transactions[0].From.ShouldBe(SampleAddress.AddressList[0]); transactions[0].To.ShouldBe(smartContractAddress); transactions[0].RefBlockNumber.ShouldBe(previousBlockHeight); transactions[0].RefBlockPrefix.ShouldBe(ByteString.CopyFrom(previousBlockHash.Value.Take(4).ToArray())); transactions[0].MethodName .ShouldBe(nameof(CrossChainContractContainer.CrossChainContractStub.ProposeCrossChainIndexing)); var crossChainBlockDataInParam = CrossChainBlockData.Parser.ParseFrom(transactions[0].Params); Assert.Equal(crossChainBlockData, crossChainBlockDataInParam); }
/// <summary> /// Propose cross chain block data to be indexed and create a proposal. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Empty ProposeCrossChainIndexing(CrossChainBlockData input) { AssertValidCrossChainIndexingProposer(Context.Sender); ClearExpiredCrossChainIndexingProposalIfExists(); AssertValidCrossChainDataBeforeIndexing(input); ProposeCrossChainBlockData(input, Context.Sender); return(new Empty()); }
public async Task GenerateTransactions_Test() { var sideChainId = 123; var previousBlockHash = HashHelper.ComputeFrom("PreviousBlockHash"); var previousBlockHeight = 1; var crossChainBlockData = new CrossChainBlockData { }; var cachingCount = 5; for (int i = 1; i < cachingCount + CrossChainConstants.DefaultBlockCacheEntityCount; i++) { var sideChainBlockData = new SideChainBlockData() { ChainId = sideChainId, Height = (i + 1), TransactionStatusMerkleTreeRoot = HashHelper.ComputeFrom((sideChainId + 1).ToString()) }; if (i <= CrossChainConstants.DefaultBlockCacheEntityCount) { crossChainBlockData.SideChainBlockDataList.Add(sideChainBlockData); } } var crossChainTransactionInput = new CrossChainTransactionInput { Value = crossChainBlockData.ToByteString(), MethodName = nameof(CrossChainContractImplContainer.CrossChainContractImplStub.ProposeCrossChainIndexing), PreviousBlockHeight = previousBlockHeight }; _crossChainTestHelper.AddFakeCrossChainTransactionInput(previousBlockHash, crossChainTransactionInput); // AddFakeCacheData(new Dictionary<int, List<ICrossChainBlockEntity>> {{sideChainId, sideChainBlockInfoCache}}); await _blockStateSetManger.SetBlockStateSetAsync(new BlockStateSet { BlockHash = previousBlockHash, BlockHeight = previousBlockHeight }); var transactions = await _crossChainIndexingTransactionGenerator.GenerateTransactionsAsync(SampleAddress.AddressList[0], previousBlockHeight, previousBlockHash); transactions.Count.ShouldBe(1); transactions[0].From.ShouldBe(SampleAddress.AddressList[0]); transactions[0].To.ShouldBeNull(); transactions[0].RefBlockNumber.ShouldBe(previousBlockHeight); transactions[0].RefBlockPrefix.ShouldBe(BlockHelper.GetRefBlockPrefix(previousBlockHash)); transactions[0].MethodName .ShouldBe(nameof(CrossChainContractImplContainer.CrossChainContractImplStub.ProposeCrossChainIndexing)); var crossChainBlockDataInParam = CrossChainBlockData.Parser.ParseFrom(transactions[0].Params); Assert.Equal(crossChainBlockData, crossChainBlockDataInParam); }
/// <summary> /// Propose cross chain block data to be indexed and create a proposal. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Empty ProposeCrossChainIndexing(CrossChainBlockData input) { EnsureTransactionOnlyExecutedOnceInOneBlock(); AssertValidCrossChainIndexingProposer(Context.Sender); ClearCrossChainIndexingProposalIfExpired(); AssertValidCrossChainDataBeforeIndexing(input); ProposeCrossChainBlockData(input, Context.Sender); return(new Empty()); }
private void AssertValidCrossChainDataBeforeIndexing(CrossChainBlockData crossChainBlockData) { Assert( crossChainBlockData.ParentChainBlockDataList.Count > 0 || crossChainBlockData.SideChainBlockDataList.Count > 0, "Empty cross chain data proposed."); Assert(ValidateSideChainBlockData(crossChainBlockData.SideChainBlockDataList) && ValidateParentChainBlockData(crossChainBlockData.ParentChainBlockDataList), "Invalid cross chain data to be indexed."); }
private void CreateFakeStateData(int fakeSideChainId, SideChainBlockData fakeSideChainBlockData, long height = 1) { var fakeIndexedCrossChainBlockData = new CrossChainBlockData(); fakeIndexedCrossChainBlockData.SideChainBlockDataList.AddRange(new[] { fakeSideChainBlockData }); // mock data in state _crossChainTestHelper.AddFakeIndexedCrossChainBlockData(height, fakeIndexedCrossChainBlockData); }
public async Task GetChainInitializationContext_Success() { var parentChainId = 123; var lockedToken = 10L; var sideChainId = await InitAndCreateSideChain(parentChainId, lockedToken); var fakeSideChainBlockHash = Hash.FromString("sideChainBlockHash"); var fakeTxMerkleTreeRoot = Hash.FromString("txMerkleTreeRoot"); var sideChainBlockData = new SideChainBlockData { BlockHeaderHash = fakeSideChainBlockHash, SideChainHeight = 1, SideChainId = sideChainId, TransactionMerkleTreeRoot = fakeTxMerkleTreeRoot }; var crossChainBlockData = new CrossChainBlockData { SideChainBlockData = { sideChainBlockData } }; var indexingTx = await GenerateTransactionAsync(CrossChainContractAddress, CrossChainConstants.CrossChainIndexingMethodName, null, crossChainBlockData); var block = await MineAsync(new List <Transaction> { indexingTx }); var indexingRes = await Tester.GetTransactionResultAsync(indexingTx.GetHash()); Assert.True(indexingRes.Status == TransactionResultStatus.Mined); //not exsit chain id var chainInitializationContext = ChainInitializationContext.Parser.ParseFrom( await CallContractMethodAsync(CrossChainContractAddress, nameof(CrossChainContract.GetChainInitializationContext), new SInt32Value() { Value = parentChainId })); chainInitializationContext.ChainId.ShouldBe(0); chainInitializationContext.Creator.ShouldBeNull(); //valid chain id chainInitializationContext = ChainInitializationContext.Parser.ParseFrom( await CallContractMethodAsync(CrossChainContractAddress, nameof(CrossChainContract.GetChainInitializationContext), new SInt32Value() { Value = sideChainId })); chainInitializationContext.ChainId.ShouldBe(sideChainId); chainInitializationContext.Creator.ShouldBe(Address.FromPublicKey(Tester.KeyPair.PublicKey)); }
/// <summary> /// Propose cross chain block data to be indexed and create a proposal. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Empty ProposeCrossChainIndexing(CrossChainBlockData input) { Context.LogDebug(() => "Proposing cross chain data.."); EnsureTransactionOnlyExecutedOnceInOneBlock(); AssertAddressIsCurrentMiner(Context.Sender); ClearCrossChainIndexingProposalIfExpired(); var crossChainDataDto = ValidateCrossChainDataBeforeIndexing(input); ProposeCrossChainBlockData(crossChainDataDto, Context.Sender); return(new Empty()); }
public async Task RecordSideChainData_WithChainNotExist() { int parentChainId = 123; long lockedToken = 10; long parentChainHeightOfCreation = 10; var sideChainId1 = await InitAndCreateSideChainAsync(parentChainHeightOfCreation, parentChainId, lockedToken); // create second side chain long lockedTokenAmount = 10; await ApproveBalanceAsync(lockedTokenAmount); var sideChainCreationRequest = CreateSideChainCreationRequest(1, lockedTokenAmount, ByteString.Empty); var sideChainId2 = ChainHelper.GetChainId(2); await BlockMiningService.MineBlockAsync(new List<Transaction> { CrossChainContractStub.CreateSideChain.GetTransaction(sideChainCreationRequest) }, true); var fakeSideChainBlockHash = Hash.FromString("sideChainBlockHash"); var fakeTxMerkleTreeRoot = Hash.FromString("txMerkleTreeRoot"); var sideChainBlockData1 = CreateSideChainBlockData(fakeSideChainBlockHash, 1, sideChainId1, fakeTxMerkleTreeRoot); var sideChainBlockData2 = CreateSideChainBlockData(fakeSideChainBlockHash, 2, sideChainId2, fakeTxMerkleTreeRoot); int fakeChainId = 124; var sideChainBlockData3 = CreateSideChainBlockData(fakeSideChainBlockHash, 1, fakeChainId, fakeTxMerkleTreeRoot); var crossChainBlockData = new CrossChainBlockData { SideChainBlockData = {sideChainBlockData1, sideChainBlockData2, sideChainBlockData3} }; await BlockMiningService.MineBlockAsync(new List<Transaction> { CrossChainContractStub.RecordCrossChainData.GetTransaction(crossChainBlockData) }); var balance = await CrossChainContractStub.GetSideChainBalance.CallAsync(new SInt32Value {Value = sideChainId1}); Assert.Equal(lockedToken - 1, balance.Value); var blockHeader = await BlockchainService.GetBestChainLastBlockHeaderAsync(); var indexedCrossChainBlockData = await CrossChainContractStub.GetIndexedCrossChainBlockDataByHeight.CallAsync(new SInt64Value {Value = blockHeader.Height}); var expectedCrossChainBlocData = new CrossChainBlockData(); expectedCrossChainBlocData.SideChainBlockData.Add(sideChainBlockData1); Assert.Equal(expectedCrossChainBlocData, indexedCrossChainBlockData); }
public async Task RecordCrossChainData_WithChainInsufficientBalance() { int parentChainId = 123; long lockedToken = 2; long parentChainHeightOfCreation = 10; var sideChainId = await InitAndCreateSideChainAsync(parentChainHeightOfCreation, parentChainId, lockedToken); var fakeSideChainBlockHash = Hash.FromString("sideChainBlockHash"); var fakeTxMerkleTreeRoot = Hash.FromString("txMerkleTreeRoot"); var sideChainBlockData = CreateSideChainBlockData(fakeSideChainBlockHash, 1, sideChainId, fakeTxMerkleTreeRoot); var crossChainBlockData = new CrossChainBlockData { SideChainBlockData = { sideChainBlockData } }; var indexingTx = await GenerateTransactionAsync(CrossChainContractAddress, CrossChainConstants.CrossChainIndexingMethodName, null, crossChainBlockData); var block = await MineAsync(new List <Transaction> { indexingTx }); var indexingRes = await Tester.GetTransactionResultAsync(indexingTx.GetHash()); Assert.True(indexingRes.Status == TransactionResultStatus.Mined); var fakeSideChainBlockHash2 = Hash.FromString("sideChainBlockHash2"); var fakeTxMerkleTreeRoot2 = Hash.FromString("txMerkleTreeRoot2"); sideChainBlockData = CreateSideChainBlockData(fakeSideChainBlockHash2, 2, sideChainId, fakeTxMerkleTreeRoot2); crossChainBlockData = new CrossChainBlockData { SideChainBlockData = { sideChainBlockData } }; var indexingTx2 = await ExecuteContractWithMiningAsync(CrossChainContractAddress, nameof(CrossChainContractContainer.CrossChainContractStub.RecordCrossChainData), crossChainBlockData); Assert.True(indexingTx2.Status == TransactionResultStatus.Mined); var chainStatus = SInt32Value.Parser.ParseFrom(await CallContractMethodAsync(CrossChainContractAddress, nameof(CrossChainContractContainer.CrossChainContractStub.GetChainStatus), new SInt32Value() { Value = sideChainId })).Value; Assert.Equal((int)SideChainStatus.Terminated, chainStatus); }
public async Task RecordParentChainData_WrongHeight() { int parentChainId = 123; await InitAndCreateSideChainAsync(parentChainId); var parentChainBlockData = CreateParentChainBlockData(0, parentChainId, null); var crossChainBlockData = new CrossChainBlockData { ParentChainBlockData = {parentChainBlockData} }; var txRes = await CrossChainContractStub.RecordCrossChainData.SendWithExceptionAsync(crossChainBlockData); Assert.True(txRes.TransactionResult.Status == TransactionResultStatus.Failed); }
private CrossChainBlockData AggregateToBeReleasedCrossChainData(IEnumerable <CrossChainBlockData> toBeIndexedList) { var res = new CrossChainBlockData(); toBeIndexedList.Aggregate(res, (cur, element) => { cur.ParentChainBlockDataList.Add(element.ParentChainBlockDataList); cur.SideChainBlockDataList.Add(element.SideChainBlockDataList); return(cur); }); return(res); }
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); }