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);
        }
Пример #2
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #8
0
        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);
        }
Пример #12
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());
        }
        private bool ValidateBlockExtraDataAsync(CrossChainBlockData crossChainBlockData, ByteString extraData)
        {
            var expected =
                _crossChainIndexingDataService.ExtractCrossChainExtraDataFromCrossChainBlockData(crossChainBlockData);

            return(expected.Equals(extraData));
        }
Пример #14
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));
        }
Пример #15
0
        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());
        }
Пример #16
0
        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);
        }
Пример #17
0
        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());
        }
Пример #18
0
        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);
        }
Пример #19
0
 /// <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());
 }
Пример #20
0
        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);
        }
Пример #21
0
 /// <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());
 }
Пример #22
0
 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());
        }
Пример #26
0
        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);
        }
Пример #28
0
        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);
        }
Пример #29
0
        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);
        }