/// <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 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 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++; } }
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()); }
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 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 })); }
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); }
/// <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 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); }
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 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); } }
public ChainProfile() { CreateMap <Kernel.Chain, ChainStatusDto>() .ForMember(d => d.ChainId, opt => opt.MapFrom(s => ChainHelper.ConvertChainIdToBase58(s.Id))) .ForMember(d => d.Branches, opt => opt.MapFrom(s => s.Branches.ToDictionary(b => Hash.LoadFromBase64(b.Key).ToHex(), b => b.Value))) .ForMember(d => d.NotLinkedBlocks, opt => opt.MapFrom(s => s.NotLinkedBlocks.ToDictionary(b => Hash.LoadFromBase64(b.Key).ToHex(), b => Hash.LoadFromBase64(b.Value).ToHex()))) .Ignore(d => d.GenesisContractAddress); }
public async Task <bool> ValidateSideChainBlockDataAsync(List <SideChainBlockData> sideChainBlockDataList, Hash blockHash, long blockHeight) { var sideChainValidatedHeightDict = new Dictionary <int, long>(); // chain id => validated height foreach (var sideChainBlockData in sideChainBlockDataList) { if (!sideChainValidatedHeightDict.TryGetValue(sideChainBlockData.ChainId, out var validatedHeight)) { var height = await _readerFactory.Create(blockHash, blockHeight).GetSideChainHeight .CallAsync( new SInt32Value() { Value = sideChainBlockData.ChainId }); validatedHeight = height?.Value ?? 0; } long 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) { throw new ValidateNextTimeBlockValidationException( $"Side chain data not found, chainId: {ChainHelper.ConvertChainIdToBase58(sideChainBlockData.ChainId)}, side chain height: {targetHeight}."); } if (!cachedSideChainBlockData.Equals(sideChainBlockData)) { return(false); } sideChainValidatedHeightDict[sideChainBlockData.ChainId] = sideChainBlockData.Height; } foreach (var chainIdHeight in sideChainValidatedHeightDict) { Logger.LogTrace( $"Validated height {chainIdHeight.Value} from chain {ChainHelper.ConvertChainIdToBase58(chainIdHeight.Key)} "); } return(true); }
public Task UpdateCrossChainCacheAsync(Hash blockHash, long blockHeight, ChainIdAndHeightDict chainIdAndHeightDict) { foreach (var chainIdHeight in chainIdAndHeightDict.IdHeightDict) { // register new chain RegisterNewChain(chainIdHeight.Key, chainIdHeight.Value); // clear cross chain cache ClearOutOfDateCrossChainCache(chainIdHeight.Key, chainIdHeight.Value); Logger.LogDebug( $"Clear chain {ChainHelper.ConvertChainIdToBase58(chainIdHeight.Key)} cache by height {chainIdHeight.Value}"); } return(Task.CompletedTask); }
private async Task <List <ParentChainBlockData> > GetNonIndexedParentChainBlockDataAsync(Hash blockHash, long blockHeight) { var parentChainBlockDataList = new List <ParentChainBlockData>(); 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 = CrossChainOptions.Value.MaximalCountForIndexingParentChainBlock; 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, true); if (parentChainBlockData == null) { // 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); }
private async Task <bool> ValidateParentChainBlockDataAsync(IEnumerable <ParentChainBlockData> multiParentChainBlockData, Hash blockHash, long blockHeight) { var parentChainBlockDataList = multiParentChainBlockData.ToList(); if (parentChainBlockDataList.Count == 0) { return(true); } var parentChainId = (await _readerFactory.Create(blockHash, blockHeight).GetParentChainId .CallAsync(new Empty())).Value; if (parentChainId == 0) { // no configured parent chain return(false); } var length = parentChainBlockDataList.Count; var i = 0; var targetHeight = (await _readerFactory.Create(blockHash, blockHeight).GetParentChainHeight .CallAsync(new Empty())).Value + 1; while (i < length) { var parentChainBlockData = _blockCacheEntityConsumer.Take <ParentChainBlockData>(parentChainId, targetHeight, false); if (parentChainBlockData == null) { Logger.LogWarning( $"Parent chain data not found. ChainId: {ChainHelper.ConvertChainIdToBase58(parentChainId)}, parent chain height: {targetHeight}."); return(false); } if (!parentChainBlockDataList[i].Equals(parentChainBlockData)) { Logger.LogWarning( $"Incorrect parent chain data. ChainId: {ChainHelper.ConvertChainIdToBase58(parentChainId)}, parent chain height: {targetHeight}."); return(false); } targetHeight++; i++; } return(true); }
public bool TryAddBlockCacheEntity(IBlockCacheEntity blockCacheEntity) { if (blockCacheEntity == null) { throw new ArgumentNullException(nameof(blockCacheEntity)); } if (!_crossChainCacheEntityProvider.TryGetChainCacheEntity(blockCacheEntity.ChainId, out var chainCacheEntity)) { return(false); } var res = chainCacheEntity.TryAdd(blockCacheEntity); Logger.LogTrace( $"Cached height {blockCacheEntity.Height} from chain {ChainHelper.ConvertChainIdToBase58(blockCacheEntity.ChainId)}, {res}"); return(res); }
private BlockDto CreateBlockDto(Block block, bool includeTransactions) { if (block == null) { throw new UserFriendlyException(Error.Message[Error.NotFound], Error.NotFound.ToString()); } var bloom = block.Header.Bloom; 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(), MerkleTreeRootOfTransactionState = block.Header.MerkleTreeRootOfTransactionStatus.ToHex(), Extra = block.Header.ExtraData.ToString(), Height = block.Header.Height, Time = block.Header.Time.ToDateTime(), ChainId = ChainHelper.ConvertChainIdToBase58(block.Header.ChainId), Bloom = bloom.Length == 0 ? ByteString.CopyFrom(new byte[256]).ToBase64(): bloom.ToBase64(), SignerPubkey = block.Header.SignerPubkey.ToByteArray().ToHex() }, Body = new BlockBodyDto() { TransactionsCount = block.Body.TransactionsCount, Transactions = new List <string>() } }; if (!includeTransactions) { return(blockDto); } 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); }
public async Task Test() { var preBlockHeader = await _blockchainService.GetBestChainLastBlockHeaderAsync(); var chainContext = new ChainContext { BlockHash = preBlockHeader.GetHash(), BlockHeight = preBlockHeader.Height }; var contractMapping = await ContractAddressService.GetSystemContractNameToAddressMappingAsync(chainContext); var crossChainStub = GetTester <CrossChainContractContainer.CrossChainContractStub>( contractMapping[CrossChainSmartContractAddressNameProvider.Name], Accounts[0].KeyPair); var parentChainId = await crossChainStub.GetParentChainId.CallAsync(new Empty()); ChainHelper.ConvertChainIdToBase58(parentChainId.Value).ShouldBe("AELF"); }
public void GetChainId_By_SerialNumber_Test() { // Have tested all the conditions (195112UL ~ 11316496UL), To save time, just do some random test //var base58HashSet = new HashSet<string>(); //var intHashSet = new HashSet<int>(); // for (var i = ; i < 11316496UL; i++) for (var i = 0; i < 1000; i++) { var chainId = 2111; var base58String = ChainHelper.ConvertChainIdToBase58(chainId); base58String.Length.ShouldBe(4); var newChainId = ChainHelper.ConvertBase58ToChainId(base58String); newChainId.ShouldBe(chainId); // Uncomment this for go through all conditions // base58HashSet.Add(base58String).ShouldBe(true); // intHashSet.Add(newChainId).ShouldBe(true); } }
public override Task <HandShakeReply> CrossChainHandShake(HandShake request, ServerCallContext context) { Logger.LogDebug($"Received shake from chain {ChainHelper.ConvertChainIdToBase58(request.ChainId)}."); if (!GrpcUriHelper.TryParsePrefixedEndpoint(context.Peer, out IPEndPoint peerEndpoint)) { return(Task.FromResult(new HandShakeReply { Status = HandShakeReply.Types.HandShakeStatus.InvalidHandshakeRequest })); } _ = PublishCrossChainRequestReceivedEvent(peerEndpoint.Address.ToString(), request.ListeningPort, request.ChainId); return(Task.FromResult(new HandShakeReply { Status = HandShakeReply.Types.HandShakeStatus.Success })); }
public async Task <bool> ValidateParentChainBlockDataAsync(List <ParentChainBlockData> parentChainBlockDataList, Hash blockHash, long blockHeight) { if (parentChainBlockDataList.Count == 0) { return(true); } var parentChainId = (await _readerFactory.Create(blockHash, blockHeight).GetParentChainId .CallAsync(new Empty())).Value; if (parentChainId == 0) { // no configured parent chain return(false); } var length = parentChainBlockDataList.Count; var i = 0; var targetHeight = (await _readerFactory.Create(blockHash, blockHeight).GetParentChainHeight .CallAsync(new Empty())).Value + 1; while (i < length) { var parentChainBlockData = _blockCacheEntityConsumer.Take <ParentChainBlockData>(parentChainId, targetHeight, false); if (parentChainBlockData == null) { throw new ValidateNextTimeBlockValidationException( $"Parent chain data not found, chainId: {ChainHelper.ConvertChainIdToBase58(parentChainId)}, parent chain height: {targetHeight}."); } if (!parentChainBlockDataList[i].Equals(parentChainBlockData)) { return(false); } targetHeight++; i++; } return(true); }
public void TestChainIdGeneration() { { var chainId = ChainHelper.GetChainId(0); var chainIdBased58 = ChainHelper.ConvertChainIdToBase58(chainId); chainIdBased58.ShouldBe("2111"); var convertedChainId = ChainHelper.ConvertBase58ToChainId(chainIdBased58); convertedChainId.ShouldBe(chainId); } { var chainId = ChainHelper.GetChainId(1); var chainIdBased58 = ChainHelper.ConvertChainIdToBase58(chainId); chainIdBased58.ShouldBe("2112"); var convertedChainId = ChainHelper.ConvertBase58ToChainId(chainIdBased58); convertedChainId.ShouldBe(chainId); } { var chainIdMaxValue = ChainHelper.GetChainId(long.MaxValue); var chainIdBased58MaxValue = ChainHelper.ConvertChainIdToBase58(chainIdMaxValue); chainIdBased58MaxValue.ShouldBe("mR59"); var convertedChainIdMaxValue = ChainHelper.ConvertBase58ToChainId(chainIdBased58MaxValue); convertedChainIdMaxValue.ShouldBe(chainIdMaxValue); var chainIdMinValue = ChainHelper.GetChainId(long.MinValue); chainIdMinValue.ShouldBe(chainIdMaxValue); var chainIdBased58MinValue = ChainHelper.ConvertChainIdToBase58(chainIdMaxValue); chainIdBased58MinValue.ShouldBe(chainIdBased58MaxValue); var convertedChainIdMinValue = ChainHelper.ConvertBase58ToChainId(chainIdBased58MinValue); convertedChainIdMinValue.ShouldBe(convertedChainIdMaxValue); } { var chainIdAElf = ChainHelper.ConvertBase58ToChainId("AELF"); var chainId = ChainHelper.GetChainId(chainIdAElf + 1); var chainIdBased58 = ChainHelper.ConvertChainIdToBase58(chainId); chainIdBased58.ShouldBe("tDVV"); } }
public async Task UpdateWithLibAsync(Hash blockHash, long blockHeight) { if (CrossChainConfigOptions.CurrentValue.CrossChainDataValidationIgnored || blockHeight <= AElfConstants.GenesisBlockHeight) { return; } var chainIdHeightPairs = await GetAllChainIdHeightPairsAsync(blockHash, blockHeight); foreach (var chainIdHeight in chainIdHeightPairs.IdHeightDict) { // register new chain _crossChainCacheEntityService.RegisterNewChain(chainIdHeight.Key, chainIdHeight.Value); // clear cross chain cache _crossChainCacheEntityService.ClearOutOfDateCrossChainCache(chainIdHeight.Key, chainIdHeight.Value); Logger.LogDebug( $"Clear chain {ChainHelper.ConvertChainIdToBase58(chainIdHeight.Key)} cache by height {chainIdHeight.Value}"); } }
public override async Task RequestIndexingFromParentChain(CrossChainRequest crossChainRequest, IServerStreamWriter <ParentChainBlockData> responseStream, ServerCallContext context) { Logger.LogDebug( $"Parent Chain Server received IndexedInfo message from chain {ChainHelper.ConvertChainIdToBase58(crossChainRequest.ChainId)}."); var requestedHeight = crossChainRequest.NextHeight; var remoteChainId = crossChainRequest.ChainId; while (requestedHeight - crossChainRequest.NextHeight < GrpcCrossChainConstants.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.ChainId)} node."); return; } try { await responseStream.WriteAsync(parentChainBlockData); requestedHeight++; } catch (InvalidOperationException) { Logger.LogWarning("Failed to write into server side stream."); return; } } }
public BlockProfile() { CreateMap <Block, BlockDto>() .ForMember(d => d.BlockHash, opt => opt.MapFrom(s => s.GetHash())) .ForMember(destination => destination.BlockSize, opt => opt.MapFrom(source => source.CalculateSize())); CreateMap <BlockHeader, BlockHeaderDto>() .ForMember(d => d.MerkleTreeRootOfTransactionState, opt => opt.MapFrom(s => s.MerkleTreeRootOfTransactionStatus.ToHex())) .ForMember(d => d.Extra, opt => opt.MapFrom(s => s.ExtraData.ToString())) .ForMember(d => d.Time, opt => opt.MapFrom(s => s.Time.ToDateTime())) .ForMember(d => d.ChainId, opt => opt.MapFrom(s => ChainHelper.ConvertChainIdToBase58(s.ChainId))) .ForMember(d => d.Bloom, opt => opt.MapFrom(s => s.Bloom.Length == 0 ? ByteString.CopyFrom(new byte[256]).ToBase64() : s.Bloom.ToBase64())) .ForMember(d => d.SignerPubkey, opt => opt.MapFrom(s => s.SignerPubkey.ToByteArray().ToHex(false))); CreateMap <BlockBody, BlockBodyDto>() .ForMember(d => d.Transactions, opt => opt.MapFrom <BlockBodyResolver>()); }
public override void ConfigureServices(ServiceConfigurationContext context) { base.ConfigureServices(context); var dictionary = new Dictionary <long, Hash> { { 1, Hash.FromString("1") }, { 2, Hash.FromString("2") }, { 3, Hash.FromString("3") } }; Configure <GrpcCrossChainConfigOption>(option => { option.ListeningPort = 5001; option.ParentChainServerIp = "127.0.0.1"; option.ParentChainServerPort = 5000; }); Configure <CrossChainConfigOptions>(option => { option.ParentChainId = ChainHelper.ConvertChainIdToBase58(ChainHelper.GetChainId(1)); }); context.Services.AddTransient(provider => { var kernelTestHelper = context.Services.GetRequiredServiceLazy <KernelTestHelper>(); var mockBlockChainService = new Mock <IBlockchainService>(); mockBlockChainService.Setup(m => m.GetChainAsync()).Returns(() => { var chain = new Chain { LastIrreversibleBlockHeight = 10 }; return(Task.FromResult(chain)); }); mockBlockChainService.Setup(m => m.GetBlockHashByHeightAsync(It.IsAny <Chain>(), It.IsAny <long>(), It.IsAny <Hash>())) .Returns <Chain, long, Hash>((chain, height, hash) => { if (height > 0 && height <= 3) { return(Task.FromResult(dictionary[height])); } return(Task.FromResult <Hash>(null)); }); mockBlockChainService.Setup(m => m.GetBlockByHashAsync(It.IsAny <Hash>())).Returns <Hash>(hash => { foreach (var kv in dictionary) { if (kv.Value.Equals(hash)) { var block = kernelTestHelper.Value.GenerateBlock(kv.Key - 1, dictionary[kv.Key - 1]); return(Task.FromResult(block)); } } return(Task.FromResult <Block>(null)); }); return(mockBlockChainService.Object); }); context.Services.AddTransient(provider => { var mockBlockExtraDataService = new Mock <IBlockExtraDataService>(); mockBlockExtraDataService .Setup(m => m.GetExtraDataFromBlockHeader(It.IsAny <string>(), It.IsAny <BlockHeader>())).Returns( () => { var crossExtraData = new CrossChainExtraData() { TransactionStatusMerkleTreeRoot = Hash.FromString("SideChainBlockHeadersRoot"), }; return(ByteString.CopyFrom(crossExtraData.ToByteArray())); }); return(mockBlockExtraDataService.Object); }); context.Services.AddTransient(provider => { var mockCrossChainIndexingDataService = new Mock <ICrossChainIndexingDataService>(); mockCrossChainIndexingDataService .Setup(m => m.GetIndexedCrossChainBlockDataAsync(It.IsAny <Hash>(), It.IsAny <long>())) .Returns(() => { var crossChainBlockData = new CrossChainBlockData { SideChainBlockDataList = { new SideChainBlockData { ChainId = 123, Height = 1, TransactionStatusMerkleTreeRoot = Hash.FromString("fakeTransactionMerkleTree") } } }; return(Task.FromResult(crossChainBlockData)); }); mockCrossChainIndexingDataService .Setup(m => m.GetIndexedSideChainBlockDataAsync(It.IsAny <Hash>(), It.IsAny <long>())).Returns( () => { var indexedSideChainBlockData = new IndexedSideChainBlockData { SideChainBlockDataList = { new SideChainBlockData { ChainId = 123, Height = 1, TransactionStatusMerkleTreeRoot = Hash.FromString("fakeTransactionMerkleTree") } } }; return(Task.FromResult(indexedSideChainBlockData)); }); return(mockCrossChainIndexingDataService.Object); }); context.Services.AddTransient(provider => { var mockCrossChainClientProvider = new Mock <ICrossChainClientProvider>(); mockCrossChainClientProvider.Setup(m => m.CreateCrossChainClient(It.IsAny <CrossChainClientDto>())) .Returns(() => { var mockCrossChainClient = new Mock <ICrossChainClient>(); mockCrossChainClient.Setup(m => m.RequestChainInitializationDataAsync(It.IsAny <int>())).Returns( () => { var chainInitialization = new ChainInitializationData { CreationHeightOnParentChain = 1 }; return(Task.FromResult(chainInitialization)); }); mockCrossChainClient.Setup(m => m.RequestCrossChainDataAsync(It.IsAny <long>(), It.IsAny <Func <IBlockCacheEntity, bool> >())) .Returns(() => { var chainInitialization = new ChainInitializationData { CreationHeightOnParentChain = 1 }; return(Task.FromResult(chainInitialization)); }); return(mockCrossChainClient.Object); }); return(mockCrossChainClientProvider.Object); }); context.Services.AddSingleton <CrossChainPlugin>(); context.Services.AddSingleton <IConsensusExtraDataNameProvider, MockConsensusExtraDataProvider>(); }
private void ProposeCrossChainBlockData(CrossChainDataDto crossChainDataDto, Address proposer) { var crossChainIndexingController = GetCrossChainIndexingController(); foreach (var chainId in crossChainDataDto.GetChainIdList()) { Assert(!TryGetIndexingProposal(chainId, out _), "Chain indexing already proposed."); var proposalToken = HashHelper.ConcatAndCompute(Context.PreviousBlockHash, ConvertChainIdToHash(chainId)); var proposalCreationInput = new CreateProposalBySystemContractInput { ProposalInput = new CreateProposalInput { Params = new AcceptCrossChainIndexingProposalInput { ChainId = chainId }.ToByteString(), ContractMethodName = nameof(AcceptCrossChainIndexingProposal), ExpiredTime = Context.CurrentBlockTime.AddSeconds(CrossChainIndexingProposalExpirationTimePeriod), OrganizationAddress = crossChainIndexingController.OwnerAddress, ToAddress = Context.Self, Token = proposalToken }, OriginProposer = Context.Sender }; Context.SendInline(crossChainIndexingController.ContractAddress, nameof(AuthorizationContractContainer.AuthorizationContractReferenceState .CreateProposalBySystemContract), proposalCreationInput); var proposedCrossChainBlockData = new CrossChainBlockData(); if (crossChainDataDto.ParentChainToBeIndexedData.TryGetValue(chainId, out var parentChainToBeIndexedData)) { proposedCrossChainBlockData.ParentChainBlockDataList.Add(parentChainToBeIndexedData); } else if (crossChainDataDto.SideChainToBeIndexedData.TryGetValue(chainId, out var sideChainToBeIndexedData)) { proposedCrossChainBlockData.SideChainBlockDataList.Add(sideChainToBeIndexedData); } var crossChainIndexingProposal = new ChainIndexingProposal { ChainId = chainId, Proposer = proposer, ProposedCrossChainBlockData = proposedCrossChainBlockData }; var proposalId = Context.GenerateId(crossChainIndexingController.ContractAddress, proposalToken); crossChainIndexingProposal.ProposalId = proposalId; SetCrossChainIndexingProposalStatus(crossChainIndexingProposal, CrossChainIndexingProposalStatus.Pending); Context.Fire(new CrossChainIndexingDataProposedEvent { ProposedCrossChainData = proposedCrossChainBlockData, ProposalId = proposalId }); Context.LogDebug(() => $"Proposed cross chain data for chain {ChainHelper.ConvertChainIdToBase58(chainId)}"); } }
private async Task <List <SideChainBlockData> > GetNonIndexedSideChainBlockDataAsync(Hash blockHash, long blockHeight) { var sideChainBlockDataList = new List <SideChainBlockData>(); var sideChainIndexingInformationList = await _readerFactory.Create(blockHash, blockHeight) .GetSideChainIndexingInformationList.CallAsync(new Empty()); foreach (var sideChainIndexingInformation in sideChainIndexingInformationList.IndexingInformationList) { var libDto = await _irreversibleBlockStateProvider.GetLastIrreversibleBlockHashAndHeightAsync(); var sideChainId = sideChainIndexingInformation.ChainId; var sideChainHeightInLibValue = await _readerFactory.Create(libDto.BlockHash, libDto.BlockHeight) .GetSideChainHeight.CallAsync(new Int32Value { Value = sideChainId }); long toBeIndexedCount; long targetHeight; var sideChainHeightInLib = sideChainHeightInLibValue?.Value ?? 0; if (sideChainHeightInLib > 0) { targetHeight = sideChainIndexingInformation.IndexedHeight + 1; toBeIndexedCount = CrossChainConstants.DefaultBlockCacheEntityCount; Logger.LogTrace( $"Target height {targetHeight} of side chain " + $"{ChainHelper.ConvertChainIdToBase58(sideChainId)}."); } else if (sideChainIndexingInformation.IndexedHeight > 0) { toBeIndexedCount = 0; targetHeight = sideChainIndexingInformation.IndexedHeight + 1; } else { toBeIndexedCount = 1; targetHeight = AElfConstants.GenesisBlockHeight; Logger.LogTrace( $"Target height {targetHeight} of side chain " + $"{ChainHelper.ConvertChainIdToBase58(sideChainId)}."); } var sideChainBlockDataFromCache = new List <SideChainBlockData>(); var i = 0; while (i < toBeIndexedCount) { var sideChainBlockData = _blockCacheEntityConsumer.Take <SideChainBlockData>(sideChainIndexingInformation.ChainId, targetHeight, targetHeight == AElfConstants.GenesisBlockHeight); if (sideChainBlockData == null || sideChainBlockData.Height != targetHeight) { // no more available side chain block info break; } sideChainBlockDataFromCache.Add(sideChainBlockData); targetHeight++; i++; } if (sideChainBlockDataFromCache.Count > 0) { Logger.LogTrace( $"Got height [{sideChainBlockDataFromCache.First().Height} - {sideChainBlockDataFromCache.Last().Height} ]" + $" from side chain {ChainHelper.ConvertChainIdToBase58(sideChainIndexingInformation.ChainId)}."); sideChainBlockDataList.AddRange(sideChainBlockDataFromCache); } } return(sideChainBlockDataList); }