public async Task RechargeForSideChain_ChainNoExist() { var parentChainId = 123; long lockedTokenAmount = 10; await InitializeCrossChainContractAsync(parentChainId); await ApproveBalanceAsync(lockedTokenAmount); var otherChainId = ChainHelper.GetChainId(5); var rechargeInput = new RechargeInput() { ChainId = otherChainId, Amount = 100_000L }; await ApproveBalanceAsync(100_000L); var res = await CrossChainContractStub.Recharge.SendWithExceptionAsync(rechargeInput); var status = res.TransactionResult.Status; Assert.True(status == TransactionResultStatus.Failed); Assert.Contains("Side chain not found or not able to be recharged.", res.TransactionResult.Error); }
public async Task RequestCrossChainDataFromOtherChainsAsync() { var chainIdHeightDict = GetNeededChainIdAndHeightPairs(); foreach (var chainIdHeightPair in chainIdHeightDict) { var chainIdBased58 = ChainHelper.ConvertChainIdToBase58(chainIdHeightPair.Key); Logger.LogDebug( $"Try to request from chain {chainIdBased58}, from height {chainIdHeightPair.Value}"); try { var client = await _crossChainClientService.GetConnectedCrossChainClientAsync(chainIdHeightPair.Key); if (client != null) { await client.RequestCrossChainDataAsync(chainIdHeightPair.Value, b => _blockCacheEntityProducer.TryAddBlockCacheEntity(b)); } } catch (CrossChainRequestException e) { Logger.LogWarning(e, $"Request chain {chainIdBased58} failed."); } } }
public async Task CreateClient_Test() { var remoteChainId = ChainOptions.ChainId; var localChainId = ChainHelper.GetChainId(1); var host = "127.0.0.1"; var port = 5100; await Server.StartAsync(port); var fakeCrossChainClient = new CrossChainClientCreationContext { LocalChainId = localChainId, RemoteChainId = remoteChainId, IsClientToParentChain = false, RemoteServerHost = host, RemoteServerPort = port }; await _crossChainClientService.CreateClientAsync(fakeCrossChainClient); var res = _grpcCrossChainClientProvider.TryGetClient(remoteChainId, out var client); Assert.True(res); await client.ConnectAsync(); Assert.True(client.IsConnected); await client.CloseAsync(); Assert.False(client.IsConnected); }
public override Empty CrossChainCreateToken(CrossChainCreateTokenInput input) { var tokenContractAddress = State.CrossChainTransferWhiteList[input.FromChainId]; Assert(tokenContractAddress != null, $"Token contract address of chain {ChainHelper.ConvertChainIdToBase58(input.FromChainId)} not registered."); var originalTransaction = Transaction.Parser.ParseFrom(input.TransactionBytes); AssertCrossChainTransaction(originalTransaction, tokenContractAddress, nameof(ValidateTokenInfoExists)); var originalTransactionId = originalTransaction.GetHash(); CrossChainVerify(originalTransactionId, input.ParentChainHeight, input.FromChainId, input.MerklePath); ValidateTokenInfoExistsInput validateTokenInfoExistsInput = ValidateTokenInfoExistsInput.Parser.ParseFrom(originalTransaction.Params); RegisterTokenInfo(new TokenInfo { Symbol = validateTokenInfoExistsInput.Symbol, TokenName = validateTokenInfoExistsInput.TokenName, TotalSupply = validateTokenInfoExistsInput.TotalSupply, Decimals = validateTokenInfoExistsInput.Decimals, Issuer = validateTokenInfoExistsInput.Issuer, IsBurnable = validateTokenInfoExistsInput.IsBurnable, IsProfitable = validateTokenInfoExistsInput.IsProfitable, IssueChainId = validateTokenInfoExistsInput.IssueChainId }); return(new Empty()); }
public async Task RequestCrossChainData_Test() { var chainId = ChainHelper.GetChainId(ChainHelper.ConvertBase58ToChainId("AELF") + 1); var remoteChainId = ChainOptions.ChainId; var height = 2; var port = 5000; await Server.StartAsync(port); var grpcClientInitializationContext = new GrpcClientInitializationContext { RemoteChainId = chainId, LocalChainId = ChainHelper.ConvertBase58ToChainId("AELF"), DialTimeout = 1000, UriStr = string.Concat(Host, ":", port) }; var client = new ClientForSideChain(grpcClientInitializationContext); _grpcCrossChainCommunicationTestHelper.GrpcCrossChainClients.TryAdd(remoteChainId, client); _grpcCrossChainCommunicationTestHelper.FakeSideChainBlockDataEntityCacheOnServerSide(height); await client.RequestCrossChainDataAsync(height, b => _blockCacheEntityProducer.TryAddBlockCacheEntity(b)); var clientBlockDataEntityCache = GrpcCrossChainCommunicationTestHelper.ClientBlockDataEntityCache; var sideChainBlockData = new SideChainBlockData { Height = height }; Assert.Contains(sideChainBlockData, clientBlockDataEntityCache); Dispose(); }
public async Task <ChainInitializationData> GetChainInitializationDataAsync() { // Default Initialization Data return(new ChainInitializationData { Creator = SampleAccount.Accounts.First().Address, ChainId = ChainHelper.GetChainId(1), ChainCreatorPrivilegePreserved = false, ChainInitializationConsensusInfo = new ChainInitializationConsensusInfo { InitialConsensusData = new MinerListWithRoundNumber { MinerList = new MinerList() { Pubkeys = { SampleAccount.Accounts.Take(3) .Select(a => ByteString.CopyFrom(a.KeyPair.PublicKey)) } } }.ToByteString() }, CreationHeightOnParentChain = 100, CreationTimestamp = TimestampHelper.GetUtcNow(), NativeTokenInfoData = new TokenInfo { Symbol = "ELF", TokenName = "ELF", Decimals = 8, TotalSupply = 100_000_000_000_000_000, Issuer = SampleAccount.Accounts.First().Address, IssueChainId = ParentChainId, }.ToByteString(),
public async Task GetAllChainIdHeightPairsAtLibAsync_Test() { { var allChainIdAndHeightResult = await _crossChainIndexingDataService.GetAllChainIdHeightPairsAtLibAsync(); allChainIdAndHeightResult.ShouldBe(new ChainIdAndHeightDict()); } _crossChainTestHelper.SetFakeLibHeight(2); { var allChainIdAndHeightResult = await _crossChainIndexingDataService.GetAllChainIdHeightPairsAtLibAsync(); allChainIdAndHeightResult.ShouldBe(new ChainIdAndHeightDict()); } var parentChainId = ChainHelper.GetChainId(10); _crossChainTestHelper.AddFakeParentChainIdHeight(parentChainId, 1); var sideChainId = ChainHelper.GetChainId(100); _crossChainTestHelper.AddFakeSideChainIdHeight(sideChainId, 0); { var allChainIdAndHeightResult = await _crossChainIndexingDataService.GetAllChainIdHeightPairsAtLibAsync(); allChainIdAndHeightResult.IdHeightDict[parentChainId].ShouldBe(1); allChainIdAndHeightResult.IdHeightDict[sideChainId].ShouldBe(0); } }
public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); Configure <EconomicOptions>(configuration.GetSection("Economic")); Configure <ChainOptions>(option => { option.ChainId = ChainHelper.ConvertBase58ToChainId(context.Services.GetConfiguration()["ChainId"]); option.ChainType = context.Services.GetConfiguration().GetValue("ChainType", ChainType.MainChain); option.NetType = context.Services.GetConfiguration().GetValue("NetType", NetType.MainNet); }); Configure <HostSmartContractBridgeContextOptions>(options => { options.ContextVariables[ContextVariableDictionary.NativeSymbolName] = context.Services .GetConfiguration().GetValue("Economic:Symbol", "ELF"); }); Configure <ContractOptions>(configuration.GetSection("Contract")); Configure <ContractOptions>(options => { options.GenesisContractDir = Path.Combine(context.Services.GetHostingEnvironment().ContentRootPath, "genesis"); }); }
public async Task Create_SideChain() { await InitializeCrossChainContractAsync(); long lockedTokenAmount = 10; await ApproveBalanceAsync(lockedTokenAmount); // Create proposal and approve var proposalId = await CreateSideChainProposalAsync(1, lockedTokenAmount, ByteString.CopyFromUtf8("Test")); await ApproveWithMinersAsync(proposalId); var transactionResult = await ReleaseProposalAsync(proposalId); var chainId = CreationRequested.Parser.ParseFrom(transactionResult.Logs[1].NonIndexed).ChainId; var creator = CreationRequested.Parser.ParseFrom(transactionResult.Logs[1].NonIndexed).Creator; Assert.True(creator == DefaultSender); var chainStatus = await CrossChainContractStub.GetChainStatus.CallAsync(new SInt32Value { Value = chainId }); Assert.True(chainStatus.Value == (int)SideChainStatus.Active); var parentChain = await CrossChainContractStub.GetParentChainId.CallAsync(new Empty()); Assert.True(parentChain.Equals(new SInt32Value { Value = ChainHelper.ConvertBase58ToChainId("AELF") })); }
public async Task <OsBlockchainNodeContext> InitialChainAsyncWithAuthAsync( Action <List <GenesisSmartContractDto> > configureSmartContract = null) { var osBlockchainNodeContextService = Application.ServiceProvider.GetRequiredService <IOsBlockchainNodeContextService>(); var contractOptions = Application.ServiceProvider.GetService <IOptionsSnapshot <ContractOptions> >().Value; var consensusOptions = Application.ServiceProvider.GetService <IOptionsSnapshot <ConsensusOptions> >().Value; consensusOptions.StartTimestamp = TimestampHelper.GetUtcNow(); var dto = new OsBlockchainNodeContextStartDto { ChainId = ChainHelper.ConvertBase58ToChainId("AELF"), ZeroSmartContract = typeof(BasicContractZero), SmartContractRunnerCategory = SmartContractTestConstants.TestRunnerCategory, ContractDeploymentAuthorityRequired = contractOptions.ContractDeploymentAuthorityRequired }; dto.InitializationSmartContracts.AddGenesisSmartContract( ConsensusContractCode, ConsensusSmartContractAddressNameProvider.Name, GenerateConsensusInitializationCallList(consensusOptions)); configureSmartContract?.Invoke(dto.InitializationSmartContracts); return(await osBlockchainNodeContextService.StartAsync(dto)); }
public async Task RechargeForSideChain_ChainNoExist() { var parentChainId = 123; long lockedTokenAmount = 10; await InitializeCrossChainContractAsync(parentChainId); await ApproveBalanceAsync(lockedTokenAmount); var otherChainId = ChainHelper.GetChainId(5); var rechargeInput = new RechargeInput() { ChainId = otherChainId, Amount = 100_000L }; await ApproveBalanceAsync(100_000L); var transactionResult = await ExecuteContractWithMiningAsync(CrossChainContractAddress, nameof(CrossChainContractContainer.CrossChainContractStub.Recharge), rechargeInput); transactionResult.Status.ShouldBe(TransactionResultStatus.Failed); transactionResult.Error.Contains("Side chain not found or not able to be recharged.").ShouldBeTrue(); }
public void CreateCrossChainClient_Test() { var remoteChainId = ChainOptions.ChainId; var localChainId = ChainHelper.GetChainId(1); var host = "127.0.0.1"; var port = 5000; var crossChainClientDto = new CrossChainClientDto { LocalChainId = localChainId, RemoteChainId = remoteChainId, IsClientToParentChain = false, RemoteServerHost = host, RemoteServerPort = port }; var client = _grpcCrossChainClientProvider.CreateCrossChainClient(crossChainClientDto); var isClientCached = _grpcCrossChainClientProvider.TryGetClient(remoteChainId, out _); Assert.False(isClientCached); Assert.True(client.RemoteChainId == remoteChainId); Assert.False(client.IsConnected); Assert.Equal(remoteChainId, client.RemoteChainId); var expectedUriStr = string.Concat(host, ":", "5000"); Assert.Equal(expectedUriStr, client.TargetUriString); }
/// <summary> /// Get the current status of the block chain. /// </summary> /// <returns></returns> public async Task <ChainStatusDto> GetChainStatusAsync() { var basicContractZero = _smartContractAddressService.GetZeroSmartContractAddress(); var chain = await _blockchainService.GetChainAsync(); var branches = chain.Branches.ToDictionary(b => HashHelper.Base64ToHash(b.Key).ToHex(), b => b.Value); var notLinkedBlocks = chain.NotLinkedBlocks.ToDictionary(b => HashHelper.Base64ToHash(b.Key).ToHex(), b => HashHelper.Base64ToHash(b.Value).ToHex()); return(new ChainStatusDto { ChainId = ChainHelper.ConvertChainIdToBase58(chain.Id), GenesisContractAddress = basicContractZero?.GetFormatted(), Branches = branches, NotLinkedBlocks = notLinkedBlocks, LongestChainHeight = chain.LongestChainHeight, LongestChainHash = chain.LongestChainHash?.ToHex(), GenesisBlockHash = chain.GenesisBlockHash.ToHex(), LastIrreversibleBlockHash = chain.LastIrreversibleBlockHash?.ToHex(), LastIrreversibleBlockHeight = chain.LastIrreversibleBlockHeight, BestChainHash = chain.BestChainHash?.ToHex(), BestChainHeight = chain.BestChainHeight }); }
public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); Configure <EconomicOptions>(configuration.GetSection("Economic")); Configure <ChainOptions>(option => { option.ChainId = ChainHelper.ConvertBase58ToChainId(context.Services.GetConfiguration()["ChainId"]); option.ChainType = context.Services.GetConfiguration().GetValue("ChainType", ChainType.MainChain); option.NetType = context.Services.GetConfiguration().GetValue("NetType", NetType.MainNet); }); Configure <HostSmartContractBridgeContextOptions>(options => { options.ContextVariables[ContextVariableDictionary.NativeSymbolName] = context.Services .GetConfiguration().GetValue("Economic:Symbol", "ELF"); options.ContextVariables[ContextVariableDictionary.PayTxFeeSymbolList] = context.Services .GetConfiguration() .GetValue("Economic:SymbolListToPayTxFee", "WRITE,READ,STORAGE,TRAFFIC"); options.ContextVariables[ContextVariableDictionary.PayRentalSymbolList] = context.Services .GetConfiguration().GetValue("Economic:SymbolListToPayRental", "CPU,RAM,DISK,NET"); }); Configure <ContractOptions>(configuration.GetSection("Contract")); Configure <ContractOptions>(options => { options.GenesisContractDir = Path.Combine(context.Services.GetHostingEnvironment().ContentRootPath, "genesis"); options.ContractFeeStrategyAcsList = new List <string> { "acs1", "acs8" }; }); }
public override async Task RequestIndexingFromParentChain(CrossChainRequest crossChainRequest, IServerStreamWriter <ParentChainBlockData> responseStream, ServerCallContext context) { Logger.LogTrace( $"Parent Chain Server received IndexedInfo message from chain {ChainHelper.ConvertChainIdToBase58(crossChainRequest.FromChainId)}."); var requestedHeight = crossChainRequest.NextHeight; var remoteChainId = crossChainRequest.FromChainId; while (requestedHeight - crossChainRequest.NextHeight < CrossChainCommunicationConstants.MaximalIndexingCount) { var parentChainBlockData = await _crossChainResponseService.ResponseParentChainBlockDataAsync(requestedHeight, remoteChainId); if (parentChainBlockData == null) { break; } if (context.Status.StatusCode != Status.DefaultSuccess.StatusCode) { Logger.LogTrace( $"Disconnected with side chain {ChainHelper.ConvertChainIdToBase58(crossChainRequest.FromChainId)} node."); return; } Logger.LogTrace($"Response parent chain data {parentChainBlockData.Height}"); await responseStream.WriteAsync(parentChainBlockData); requestedHeight++; } }
private async Task <bool> ValidateSideChainBlockDataAsync( IEnumerable <SideChainBlockData> multiSideChainBlockData, Hash blockHash, long blockHeight) { var sideChainValidatedHeightDict = new Dictionary <int, long>(); // chain id => validated height foreach (var sideChainBlockData in multiSideChainBlockData) { if (!sideChainValidatedHeightDict.TryGetValue(sideChainBlockData.ChainId, out var validatedHeight)) { var height = await _contractReaderFactory .Create(new ContractReaderContext { BlockHash = blockHash, BlockHeight = blockHeight, ContractAddress = await GetCrossChainContractAddressAsync(new ChainContext { BlockHash = blockHash, BlockHeight = blockHeight }) }).GetSideChainHeight .CallAsync( new Int32Value() { Value = sideChainBlockData.ChainId }); validatedHeight = height?.Value ?? 0; } var targetHeight = validatedHeight + 1; if (targetHeight != sideChainBlockData.Height) { // this should not happen if it is good data. return(false); } var cachedSideChainBlockData = _blockCacheEntityConsumer.Take <SideChainBlockData>(sideChainBlockData.ChainId, targetHeight, false); if (cachedSideChainBlockData == null) { Logger.LogDebug( $"Side chain data not found. ChainId: {ChainHelper.ConvertChainIdToBase58(sideChainBlockData.ChainId)}, side chain height: {targetHeight}."); return(false); } if (!cachedSideChainBlockData.Equals(sideChainBlockData)) { Logger.LogDebug( $"Incorrect side chain data. ChainId: {ChainHelper.ConvertChainIdToBase58(sideChainBlockData.ChainId)}, side chain height: {targetHeight}."); return(false); } sideChainValidatedHeightDict[sideChainBlockData.ChainId] = sideChainBlockData.Height; } return(true); }
public async Task ResponseParentChainBlockData_Test() { var chainId = ChainHelper.GetChainId(1); var height = 3; var res = await _chainResponseService.ResponseParentChainBlockDataAsync(height, chainId); Assert.True(res.Height == 3); }
public async Task ResponseParentChainBlockData_WithoutBlock_Test() { var chainId = ChainHelper.GetChainId(1); var height = 5; var res = await _chainResponseService.ResponseParentChainBlockDataAsync(height, chainId); Assert.Null(res); }
public async Task CreateClientAsync(CrossChainClientDto crossChainClientDto) { Logger.LogDebug( $"Handle cross chain request received event from chain {ChainHelper.ConvertChainIdToBase58(crossChainClientDto.RemoteChainId)}."); crossChainClientDto.LocalChainId = _localChainId; await _crossChainClientService.CreateClientAsync(crossChainClientDto); }
public override Task <HandShakeReply> CrossChainHandShake(HandShake request, ServerCallContext context) { Logger.LogTrace($"Received shake from chain {ChainHelper.ConvertChainIdToBase58(request.FromChainId)}."); _ = PublishCrossChainRequestReceivedEvent(request.Host, request.ListeningPort, request.FromChainId); return(Task.FromResult(new HandShakeReply { Success = true })); }
private async Task ConnectAsync(ICrossChainClient client) { if (client.IsConnected) { return; } Logger.LogDebug($"Try connect with chain {ChainHelper.ConvertChainIdToBase58(client.RemoteChainId)}"); await client.ConnectAsync(); }
public override async Task <ChainInitializationData> RequestChainInitializationDataFromParentChain(SideChainInitializationRequest request, ServerCallContext context) { Logger.LogTrace( $"Received initialization data request from chain {ChainHelper.ConvertChainIdToBase58(request.ChainId)}"); var sideChainInitializationResponse = await _crossChainResponseService.ResponseChainInitializationDataFromParentChainAsync(request.ChainId); return(sideChainInitializationResponse); }
public SideChainInitializationDataProvider(IOptionsSnapshot <ChainOptions> chainOptions, IOptionsSnapshot <CrossChainConfigOptions> crossChainConfigOptions, IChainInitializationDataPlugin chainInitializationDataPlugin, IBlockchainService blockchainService) { _chainOptions = chainOptions.Value; _chainInitializationDataPlugin = chainInitializationDataPlugin; _blockchainService = blockchainService; ParentChainId = ChainHelper.ConvertBase58ToChainId(crossChainConfigOptions.Value.ParentChainId); }
/// <summary> /// Get information about a given block by block hash. Otionally with the list of its transactions. /// </summary> /// <param name="blockHash">block hash</param> /// <param name="includeTransactions">include transactions or not</param> /// <returns></returns> public async Task <BlockDto> GetBlockAsync(string blockHash, bool includeTransactions = false) { Hash realBlockHash; try { realBlockHash = HashHelper.HexStringToHash(blockHash); } catch { throw new UserFriendlyException(Error.Message[Error.InvalidBlockHash], Error.InvalidBlockHash.ToString()); } var block = await GetBlockAsync(realBlockHash); if (block == null) { throw new UserFriendlyException(Error.Message[Error.NotFound], Error.NotFound.ToString()); } var blockDto = new BlockDto { BlockHash = block.GetHash().ToHex(), Header = new BlockHeaderDto { PreviousBlockHash = block.Header.PreviousBlockHash.ToHex(), MerkleTreeRootOfTransactions = block.Header.MerkleTreeRootOfTransactions.ToHex(), MerkleTreeRootOfWorldState = block.Header.MerkleTreeRootOfWorldState.ToHex(), Extra = block.Header.ExtraData.ToString(), Height = block.Header.Height, Time = block.Header.Time.ToDateTime(), ChainId = ChainHelper.ConvertChainIdToBase58(block.Header.ChainId), Bloom = block.Header.Bloom.ToByteArray().ToHex(), SignerPubkey = block.Header.SignerPubkey.ToByteArray().ToHex() }, Body = new BlockBodyDto() { TransactionsCount = block.Body.TransactionsCount, Transactions = new List <string>() } }; if (includeTransactions) { var transactions = block.Body.TransactionIds; var txs = new List <string>(); foreach (var transactionId in transactions) { txs.Add(transactionId.ToHex()); } blockDto.Body.Transactions = txs; } return(blockDto); }
private async Task <List <ParentChainBlockData> > GetNonIndexedParentChainBlockDataAsync(Hash blockHash, long blockHeight) { var parentChainBlockDataList = new List <ParentChainBlockData>(); var libExists = await _irreversibleBlockStateProvider.ValidateIrreversibleBlockExistingAsync(); if (!libExists) { return(parentChainBlockDataList); } var returnValue = await _readerFactory.Create(blockHash, blockHeight).GetParentChainId .CallAsync(new Empty()); var parentChainId = returnValue?.Value ?? 0; if (parentChainId == 0) { //Logger.LogTrace("No configured parent chain"); // no configured parent chain return(parentChainBlockDataList); } int length = CrossChainConstants.DefaultBlockCacheEntityCount; var heightInState = (await _readerFactory.Create(blockHash, blockHeight).GetParentChainHeight .CallAsync(new Empty())).Value; var targetHeight = heightInState + 1; Logger.LogTrace($"Target height {targetHeight}"); var i = 0; while (i < length) { var parentChainBlockData = _blockCacheEntityConsumer.Take <ParentChainBlockData>(parentChainId, targetHeight, false); if (parentChainBlockData == null || parentChainBlockData.Height != targetHeight) { // no more available parent chain block info break; } parentChainBlockDataList.Add(parentChainBlockData); targetHeight++; i++; } if (parentChainBlockDataList.Count > 0) { Logger.LogTrace( $"Got height [{parentChainBlockDataList.First().Height} - {parentChainBlockDataList.Last().Height} ]" + $" from parent chain {ChainHelper.ConvertChainIdToBase58(parentChainId)}."); } return(parentChainBlockDataList); }
public async Task GetChainStatus_NotExist() { var chainId = ChainHelper.GetChainId(1); var res = await CrossChainContractStub.GetChainStatus.SendWithExceptionAsync(new SInt32Value { Value = chainId }); var status = res.TransactionResult.Status; Assert.True(status == TransactionResultStatus.Failed); Assert.Contains("Side chain not found.", res.TransactionResult.Error); }
public async Task CrossChainServerStart_Test() { var localChainId = ChainHelper.GetChainId(1); await _grpcCrossChainServerNodePlugin.StartAsync(localChainId); Assert.True(_grpcCrossChainServer.IsStarted); await _grpcCrossChainServerNodePlugin.ShutdownAsync(); Assert.False(_grpcCrossChainServer.IsStarted); }
/// <summary> /// Get id of the chain. /// </summary> /// <returns>ChainId</returns> public async Task <int> GetChainIdAsync() { var url = GetRequestUrl(_baseUrl, "api/blockChain/chainStatus"); var statusDto = await _httpService.GetResponseAsync <ChainStatusDto>(url); var base58ChainId = statusDto.ChainId; var chainId = ChainHelper.ConvertBase58ToChainId(base58ChainId); return(chainId); }
public async Task ValidateBlockBeforeAttach_Test() { var fakeMerkleTreeRoot1 = Hash.FromString("fakeMerkleTreeRoot1"); var fakeSideChainId = ChainHelper.ConvertBase58ToChainId("2112"); var fakeSideChainBlockData = CreateSideChainBlockData(fakeSideChainId, 1, fakeMerkleTreeRoot1); var sideChainTxMerkleTreeRoot = ComputeRootHash(new[] { fakeSideChainBlockData }); var block = CreateFilledBlock(sideChainTxMerkleTreeRoot); var res = await _crossChainBlockValidationProvider.ValidateBeforeAttachAsync(block); Assert.True(res); }
public async Task RequestCrossChainDataFromOtherChainsAsync() { var chainIdHeightDict = _crossChainService.GetNeededChainIdAndHeightPairs(); foreach (var chainIdHeightPair in chainIdHeightDict) { Logger.LogTrace( $"Try to request from chain {ChainHelper.ConvertChainIdToBase58(chainIdHeightPair.Key)}, from height {chainIdHeightPair.Value}"); await _crossChainClientService.RequestCrossChainDataAsync(chainIdHeightPair.Key, chainIdHeightPair.Value); } }